From b64114ab23214bdc7a4821f0c8f78e3bda9728ac Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Thu, 1 Aug 2019 10:48:36 -0700 Subject: [PATCH 01/11] cant slice a null array rancher/rancher#21816 --- .../components/cru-cluster-template-questions/component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/shared/addon/components/cru-cluster-template-questions/component.js b/lib/shared/addon/components/cru-cluster-template-questions/component.js index 5a25408ad..1bd4c5ba2 100644 --- a/lib/shared/addon/components/cru-cluster-template-questions/component.js +++ b/lib/shared/addon/components/cru-cluster-template-questions/component.js @@ -196,7 +196,7 @@ export default Component.extend({ ignoreFields, } = this; - allQuestions = allQuestions.slice(); + allQuestions = ( allQuestions || []).slice(); allQuestions.forEach((q) => { if (ignoreFields.includes(q.variable)) { From 3b65839c0687858d185d5723ac4fb92d74d80efd Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Thu, 1 Aug 2019 10:54:15 -0700 Subject: [PATCH 02/11] check if override has satisfies rancher/rancher#21898 --- lib/shared/addon/components/form-versions/component.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/shared/addon/components/form-versions/component.js b/lib/shared/addon/components/form-versions/component.js index 1eb271551..d3e304132 100644 --- a/lib/shared/addon/components/form-versions/component.js +++ b/lib/shared/addon/components/form-versions/component.js @@ -78,7 +78,10 @@ export default Component.extend({ // the template creator lets them override this but the initial version is a dot x so we should choose the biggest version in the .x range maxVersion = maxSatisfying(versions, initialVersion); } else { - supportedVersionsRange = overrideMatch.satisfies; + if (overrideMatch.satisfies) { + supportedVersionsRange = overrideMatch.satisfies; + } + maxVersion = maxSatisfying(versions, supportedVersionsRange); } } From 4ef13c811981ac33e892fcdc8a412ae6053adc4c Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Thu, 1 Aug 2019 11:07:45 -0700 Subject: [PATCH 03/11] remove erroneous check in init form-versions for ctr create rancher/rancher#21882 --- lib/shared/addon/components/form-versions/component.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/shared/addon/components/form-versions/component.js b/lib/shared/addon/components/form-versions/component.js index d3e304132..d95da7e74 100644 --- a/lib/shared/addon/components/form-versions/component.js +++ b/lib/shared/addon/components/form-versions/component.js @@ -54,7 +54,6 @@ export default Component.extend({ initialVersion, defaultK8sVersion, applyClusterTemplate = false, - clusterTemplateCreate = false, clusterTemplateQuestions = [], } = this; @@ -70,7 +69,7 @@ export default Component.extend({ let maxVersion = maxSatisfying(versions, defaultK8sVersionRange); - if (applyClusterTemplate || clusterTemplateCreate) { + if ( applyClusterTemplate ) { var overrideMatch = ( clusterTemplateQuestions || [] ).findBy('variable', 'rancherKubernetesEngineConfig.kubernetesVersion'); if (overrideMatch) { From 9c22f4769219886ff2683f5254718369b2034f6b Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Thu, 1 Aug 2019 12:30:49 -0700 Subject: [PATCH 04/11] Apply cloudconfig answers and remove when consuming ctr and changes rancher/rancher#21815 --- .../cru-cloud-provider/component.js | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/lib/shared/addon/components/cru-cloud-provider/component.js b/lib/shared/addon/components/cru-cloud-provider/component.js index 42bca069c..cb679f786 100644 --- a/lib/shared/addon/components/cru-cloud-provider/component.js +++ b/lib/shared/addon/components/cru-cloud-provider/component.js @@ -8,6 +8,7 @@ import { alias } from '@ember/object/computed'; import { isEmpty } from '@ember/utils'; import C from 'ui/utils/constants'; import { azure as AzureInfo } from './cloud-provider-info'; +import { next } from '@ember/runloop'; const azureDefaults = C.AZURE_DEFAULTS; const GENERIC_PATH = 'cluster.rancherKubernetesEngineConfig.cloudProvider.cloudConfig'; @@ -110,30 +111,47 @@ export default Component.extend({ 'clusterTemplateCreate', 'applyClusterTemplate', 'clusterTemplateRevision.questions', + 'clusterTemplateRevision.id', function() { let { clusterTemplateRevision, applyClusterTemplate } = this; - if (applyClusterTemplate && clusterTemplateRevision && clusterTemplateRevision.questions) { - let found = clusterTemplateRevision.questions.filter((ctr) => { - return ctr.variable.includes('rancherKubernetesEngineConfig.cloudProvider'); - }); + if (applyClusterTemplate && clusterTemplateRevision) { + if (clusterTemplateRevision.questions) { + let found = clusterTemplateRevision.questions.filter((ctr) => { + return ctr.variable.includes('rancherKubernetesEngineConfig.cloudProvider'); + }); - return found.length >= 1; + if (found.length === 0 && this.selectedCloudProvider !== 'none') { + set(this, 'selectedCloudProvider', 'none'); + } + + return found.length >= 1; + } else { + if (this.configName) { + next(() => { + set(this, 'selectedCloudProvider', this.configName); + }); + } + } + } else { + if (!this.configName) { + next(() => { + set(this, 'selectedCloudProvider', 'none'); + }); + } } return false; }), - isCreateClusterOrClusterTemplate: computed('', function() { - const { clusterTemplateCreate, applyClusterTemplate } = this; + isCreateClusterOrClusterTemplate: computed('applyClusterTemplate', function() { + const { applyClusterTemplate } = this; - if (!clusterTemplateCreate && !applyClusterTemplate) { - return true; - } else if (clusterTemplateCreate) { + if (applyClusterTemplate) { + return false; + } else { return true; } - - return false; }), checkDefaults(record) { From 8b85cfb3115a3845cecfbd3383b06f5343aa6013 Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Thu, 1 Aug 2019 12:32:53 -0700 Subject: [PATCH 05/11] Refresh the page when moving from using a cluster template to not --- lib/global-admin/addon/clusters/new/launch/route.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/global-admin/addon/clusters/new/launch/route.js b/lib/global-admin/addon/clusters/new/launch/route.js index fe449346e..cef3af657 100644 --- a/lib/global-admin/addon/clusters/new/launch/route.js +++ b/lib/global-admin/addon/clusters/new/launch/route.js @@ -14,6 +14,11 @@ export default Route.extend({ _cachedClusterDetails: null, beforeModel(transition) { + if (transition && transition.queryParamsOnly && isEmpty(transition.queryParams.clusterTemplateRevision)) { + // there is too much to reset and ensure is correctly set when going from cluster template to none, just refresh the page. + return window.location.href = window.location.href.split('?')[0]; + } + let { me: { hasAdmin: globalAdmin = false } } = this.access; if (!globalAdmin) { From 0560869ca4d47e7e6c14662e3c9afdbf99a2b24e Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Thu, 1 Aug 2019 14:11:02 -0700 Subject: [PATCH 06/11] dont replace existing cluster object on edit when going back to form rancher/rancher#21866 --- lib/shared/addon/components/cru-cluster/component.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/shared/addon/components/cru-cluster/component.js b/lib/shared/addon/components/cru-cluster/component.js index 2c5cd47a7..2c5e611de 100644 --- a/lib/shared/addon/components/cru-cluster/component.js +++ b/lib/shared/addon/components/cru-cluster/component.js @@ -62,7 +62,11 @@ export default Component.extend(ViewNewEdit, ChildHook, { actions: { updateFromYaml(newOpts) { - this.cluster.replaceWith(newOpts); + if (this.isEdit) { + this.cluster.merge(newOpts); + } else { + this.cluster.replaceWith(newOpts); + } }, clickNext() { From 461700a2a9b0cd1073ad22cb8af4dd3810dfb0da Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Thu, 1 Aug 2019 14:55:19 -0700 Subject: [PATCH 07/11] fix cluster/cluster template validation rancher/rancher#21616 --- app/models/clustertemplaterevision.js | 6 +++++- .../cluster-driver/driver-rke/component.js | 18 ++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/models/clustertemplaterevision.js b/app/models/clustertemplaterevision.js index 8765f8c66..e36627abe 100644 --- a/app/models/clustertemplaterevision.js +++ b/app/models/clustertemplaterevision.js @@ -1,7 +1,7 @@ import Resource from '@rancher/ember-api-store/models/resource'; import { reference } from '@rancher/ember-api-store/utils/denormalize'; import { inject as service } from '@ember/service'; -import { computed, set } from '@ember/object'; +import { computed, get, set } from '@ember/object'; import { alias } from '@ember/object/computed'; export default Resource.extend({ @@ -114,6 +114,10 @@ export default Resource.extend({ validationErrors() { let errors = []; + if (!get(this, 'name')) { + errors.push('Revision name is required'); + } + if (errors.length > 0) { return errors; } diff --git a/lib/shared/addon/components/cluster-driver/driver-rke/component.js b/lib/shared/addon/components/cluster-driver/driver-rke/component.js index 45c02ebdf..7864db011 100644 --- a/lib/shared/addon/components/cluster-driver/driver-rke/component.js +++ b/lib/shared/addon/components/cluster-driver/driver-rke/component.js @@ -768,6 +768,7 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { willSave() { const { cluster, configField: field } = this; + let ok = true; this.checkKubernetesVersionSemVer(); @@ -800,12 +801,9 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { set(this, 'errors', null); - // TODO - if (this.applyClusterTemplate || this.clusterTemplateCreate) { - return true; - } else { - return this.validate(); - } + ok = this.validate(); + + return ok; }, validate() { @@ -814,8 +812,12 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { let errors = []; let config = get(this, `config`); - if ( !get(this, 'isCustom') ) { - errors.pushObjects(get(this, 'nodePoolErrors')); + if (this.clusterTemplateCreate && this.model.clusterTemplateRevision) { + errors.pushObjects(this.model.clusterTemplateRevision.validationErrors()); + } else { + if ( !get(this, 'isCustom') ) { + errors.pushObjects(get(this, 'nodePoolErrors')); + } } if ( get(config, 'services.kubeApi.podSecurityPolicy') && From c4392a5ef92c6a2d14a716fd8551277632fce195 Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Fri, 2 Aug 2019 10:32:03 -0700 Subject: [PATCH 08/11] allow users to create cluster template with azure fields empty rancher/rancher#21759 --- app/models/clustertemplaterevision.js | 2 - .../addon/clusters/new/launch/route.js | 5 - lib/global-admin/package.json | 3 +- .../cluster-driver/driver-rke/component.js | 137 +++++++++++------- .../addon/components/cru-cluster/component.js | 13 ++ .../addon/components/cru-cluster/template.hbs | 34 +++-- lib/shared/addon/mixins/new-or-edit.js | 4 + package.json | 1 + yarn.lock | 7 + 9 files changed, 132 insertions(+), 74 deletions(-) diff --git a/app/models/clustertemplaterevision.js b/app/models/clustertemplaterevision.js index e36627abe..27d33548a 100644 --- a/app/models/clustertemplaterevision.js +++ b/app/models/clustertemplaterevision.js @@ -122,8 +122,6 @@ export default Resource.extend({ return errors; } - errors = this._super(...arguments); - return errors; }, }); diff --git a/lib/global-admin/addon/clusters/new/launch/route.js b/lib/global-admin/addon/clusters/new/launch/route.js index cef3af657..fe449346e 100644 --- a/lib/global-admin/addon/clusters/new/launch/route.js +++ b/lib/global-admin/addon/clusters/new/launch/route.js @@ -14,11 +14,6 @@ export default Route.extend({ _cachedClusterDetails: null, beforeModel(transition) { - if (transition && transition.queryParamsOnly && isEmpty(transition.queryParams.clusterTemplateRevision)) { - // there is too much to reset and ensure is correctly set when going from cluster template to none, just refresh the page. - return window.location.href = window.location.href.split('?')[0]; - } - let { me: { hasAdmin: globalAdmin = false } } = this.access; if (!globalAdmin) { diff --git a/lib/global-admin/package.json b/lib/global-admin/package.json index 76c43736a..3a0277e62 100644 --- a/lib/global-admin/package.json +++ b/lib/global-admin/package.json @@ -9,7 +9,8 @@ "ember-auto-import": "*", "ember-cli-htmlbars": "*", "ember-href-to": "*", - "ember-cli-babel": "*" + "ember-cli-babel": "*", + "ember-deep-set": "*" }, "ember-addon": { "paths": [ diff --git a/lib/shared/addon/components/cluster-driver/driver-rke/component.js b/lib/shared/addon/components/cluster-driver/driver-rke/component.js index 7864db011..d0354e684 100644 --- a/lib/shared/addon/components/cluster-driver/driver-rke/component.js +++ b/lib/shared/addon/components/cluster-driver/driver-rke/component.js @@ -21,6 +21,7 @@ import ManageLabels from 'shared/mixins/manage-labels'; import { typeOf } from '@ember/utils'; import Semver, { major, minor } from 'semver'; import { on } from '@ember/object/evented'; +import deepSet from 'ember-deep-set'; const EXCLUDED_KEYS = ['extra_args']; @@ -767,7 +768,11 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { }, willSave() { - const { cluster, configField: field } = this; + const { + cluster, + configField: field, + intl, + } = this; let ok = true; this.checkKubernetesVersionSemVer(); @@ -780,19 +785,6 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { } } - if (typeOf(cluster.clearProvidersExcept) === 'function' || this.applyClusterTemplate && typeOf(cluster.buildClusterAnswersFromConfig) === 'function') { - if (this.applyClusterTemplate) { - // need to add overrides + user entry to answers on cluster, drop rkeconfig - let answers = this.buildClusterAnswersFromConfig(cluster, get(this, 'model.clusterTemplateRevision.questions')); - - this.cluster.clearConfigFieldsForClusterTemplate(); - - set(cluster, 'answers', { values: answers }); - } else { - cluster.clearProvidersExcept(field); - } - } - if (get(cluster, 'localClusterAuthEndpoint')) { if (!get(cluster, 'rancherKubernetesEngineConfig') || isEmpty(get(cluster, 'rancherKubernetesEngineConfig'))) { delete cluster.localClusterAuthEndpoint; @@ -803,21 +795,74 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { ok = this.validate(); + if (ok) { + if (typeOf(cluster.clearProvidersExcept) === 'function' || this.applyClusterTemplate && typeOf(cluster.buildClusterAnswersFromConfig) === 'function') { + if (this.applyClusterTemplate) { + let questions = get(this, 'model.clusterTemplateRevision.questions') || []; + let required = questions.filterBy('required', true); + // need to add overrides + user entry to answers on cluster, drop rkeconfig + let answers = []; + let errors = []; + + if (questions.length > 0) { + answers = this.buildClusterAnswersFromConfig(cluster, get(this, 'model.clusterTemplateRevision.questions')) + + if (required.length > 0) { + required.forEach((rq) => { + if (!answers[rq.variable]) { + errors.push(intl.t('validation.required', { key: rq.variable })); + } + }) + } + } + + if (errors.length > 0 ) { + set(this, 'errors', errors); + + return false; + } + + this.cluster.clearConfigFieldsForClusterTemplate(); + + set(cluster, 'answers', { values: answers }); + } else { + cluster.clearProvidersExcept(field); + } + } + } + return ok; }, + checkRequiredQuestionsHaveAnswers(questions, answers) { + + }, + validate() { this._super(...arguments); - let errors = []; - let config = get(this, `config`); + let errors = []; + let { config, intl } = this; - if (this.clusterTemplateCreate && this.model.clusterTemplateRevision) { - errors.pushObjects(this.model.clusterTemplateRevision.validationErrors()); + + if (this.clusterTemplateCreate) { + if (this.model.clusterTemplateRevision) { + errors.pushObjects(this.model.clusterTemplateRevision.validationErrors()); + } } else { if ( !get(this, 'isCustom') ) { errors.pushObjects(get(this, 'nodePoolErrors')); } + + if ( get(config, 'cloudProvider.name') === 'azure' ) { + Object.keys(AzureInfo).forEach((key) => { + if ( get(AzureInfo, `${ key }.required`) && !get(config, `cloudProvider.azureCloudProvider.${ key }`)) { + if ( this.isNew || this.isEdit && key !== 'aadClientSecret' ) { + errors.push(intl.t('validation.required', { key })); + } + } + }); + } } if ( get(config, 'services.kubeApi.podSecurityPolicy') && @@ -835,18 +880,6 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { const clusterOptErrors = get(this, 'clusterOptErrors') || []; - if ( get(config, 'cloudProvider.name') === 'azure' ) { - const intl = get(this, 'intl'); - - Object.keys(AzureInfo).forEach((key) => { - if ( get(AzureInfo, `${ key }.required`) && !get(config, `cloudProvider.azureCloudProvider.${ key }`)) { - if ( this.isNew || this.isEdit && key !== 'aadClientSecret' ) { - errors.push(intl.t('validation.required', { key })); - } - } - }); - } - set(this, 'errors', errors); return errors.length === 0 && clusterOptErrors.length === 0; @@ -924,29 +957,33 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { loadToken() { const cluster = get(this, 'primaryResource'); - setProperties(this, { - step: 2, - loading: true - }); - - return cluster.getOrCreateToken().then((token) => { - if ( this.isDestroyed || this.isDestroying ) { - return; - } - + if (cluster.getOrCreateToken) { setProperties(this, { - token, - loading: false + step: 2, + loading: true }); - }).catch((err) => { - if ( this.isDestroyed || this.isDestroying ) { - return; - } - get(this, 'growl').fromError('Error getting command', err); + return cluster.getOrCreateToken().then((token) => { + if ( this.isDestroyed || this.isDestroying ) { + return; + } - set(this, 'loading', false); - }); + setProperties(this, { + token, + loading: false + }); + }).catch((err) => { + if ( this.isDestroyed || this.isDestroying ) { + return; + } + + get(this, 'growl').fromError('Error getting command', err); + + set(this, 'loading', false); + }); + } else { + return; + } }, findExcludedKeys(resourceFields) { @@ -1270,7 +1307,7 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { let path = question.variable; if (!question.variable.includes('uiOverride') && question.default) { - set(primaryResource, path, question.default); + deepSet(primaryResource, path, question.default); } set(question, 'primaryResource', primaryResource); diff --git a/lib/shared/addon/components/cru-cluster/component.js b/lib/shared/addon/components/cru-cluster/component.js index 2c5e611de..c108ff1ea 100644 --- a/lib/shared/addon/components/cru-cluster/component.js +++ b/lib/shared/addon/components/cru-cluster/component.js @@ -18,6 +18,7 @@ export default Component.extend(ViewNewEdit, ChildHook, { intl: service(), access: service(), cookies: service(), + router: service(), layout, step: 1, @@ -28,6 +29,7 @@ export default Component.extend(ViewNewEdit, ChildHook, { reloadingSchema: false, schemaReloaded: false, applyClusterTemplate: false, + routeLoading: false, showClassicLauncher: false, nodePoolErrors: null, @@ -58,6 +60,17 @@ export default Component.extend(ViewNewEdit, ChildHook, { if ( isEmpty(get(this, 'cluster.id')) ){ set(this, 'newCluster', true); } + + this.router.on('routeWillChange', (/* transition */) => { + if ( !this.isDestroyed || !this.isDestroying ) { + set(this, 'routeLoading', true); + } + }); + this.router.on('routeDidChange', (/* transition */) => { + if ( !this.isDestroyed || !this.isDestroying ) { + set(this, 'routeLoading', false); + } + }); }, actions: { diff --git a/lib/shared/addon/components/cru-cluster/template.hbs b/lib/shared/addon/components/cru-cluster/template.hbs index caa2f91fc..e8e0a9893 100644 --- a/lib/shared/addon/components/cru-cluster/template.hbs +++ b/lib/shared/addon/components/cru-cluster/template.hbs @@ -82,22 +82,24 @@ {{/accordion-list}} {{/if}} -{{component driverInfo.driverComponent - applyClusterTemplate=applyClusterTemplate - clusterTemplateQuestions=model.clusterTemplateRevision.questions - clusterTemplateRevisionId=clusterTemplateRevisionId - clusterErrors=errors - mode=mode - model=model - nodePoolErrors=nodePoolErrors - nodeWhich=driverInfo.nodeWhich - originalCluster=originalCluster - otherErrors=memberErrors - save=(action "save") - close=(action "close") - registerHook=(action "registerHook") - updateFromYaml=(action "updateFromYaml") -}} +{{#unless routeLoading}} + {{component driverInfo.driverComponent + applyClusterTemplate=applyClusterTemplate + clusterTemplateQuestions=model.clusterTemplateRevision.questions + clusterTemplateRevisionId=clusterTemplateRevisionId + clusterErrors=errors + mode=mode + model=model + nodePoolErrors=nodePoolErrors + nodeWhich=driverInfo.nodeWhich + originalCluster=originalCluster + otherErrors=memberErrors + save=(action "save") + close=(action "close") + registerHook=(action "registerHook") + updateFromYaml=(action "updateFromYaml") + }} +{{/unless}} {{#if (and isEdit (not provider))}} {{top-errors errors=errors}} diff --git a/lib/shared/addon/mixins/new-or-edit.js b/lib/shared/addon/mixins/new-or-edit.js index 125304482..15c1e8dae 100644 --- a/lib/shared/addon/mixins/new-or-edit.js +++ b/lib/shared/addon/mixins/new-or-edit.js @@ -69,6 +69,10 @@ export default Mixin.create({ cb(true); }) .catch((err) => { + if ( this.isDestroyed || this.isDestroying ) { + return; + } + this.send('error', err); this.errorSaving(err); cb(false); diff --git a/package.json b/package.json index 611118b3b..575efda7c 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "ember-concurrency": "^0.8.24", "ember-copy": "^1.0.0", "ember-credit-card": "^2.4.0", + "ember-deep-set": "^0.2.0", "ember-drag-drop": "^0.4.7", "ember-engines": "^0.6.1", "ember-export-application-global": "^2.0.0", diff --git a/yarn.lock b/yarn.lock index 5958db240..036a29062 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4641,6 +4641,13 @@ ember-credit-card@^2.4.0: ember-cli-htmlbars "2.0.3" ember-model-validator "^2.18.0" +ember-deep-set@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ember-deep-set/-/ember-deep-set-0.2.0.tgz#93428b599f884c3da0550cbcc062b9ec5969a71e" + integrity sha512-3vg9Cw4CIInXzufZMQmScClg23mUw+2ybO53L51spFYP/eGaVmGduWmhrVljyl4lHKN7hW/jvG/YVWtwTPSTKA== + dependencies: + ember-cli-babel "^7.1.2" + ember-diff-attrs@^0.2.1: version "0.2.2" resolved "https://registry.yarnpkg.com/ember-diff-attrs/-/ember-diff-attrs-0.2.2.tgz#57baf6907957de004d9aff947809dfe78a054b3b" From d06879710101375ef259a60691a5de42537ff6a8 Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Fri, 2 Aug 2019 10:56:08 -0700 Subject: [PATCH 09/11] remove auto name cluster template revision rancher/rancher#21892 --- .../addon/components/cru-cluster-template/component.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/shared/addon/components/cru-cluster-template/component.js b/lib/shared/addon/components/cru-cluster-template/component.js index aaa743d5c..af3b2ab3b 100644 --- a/lib/shared/addon/components/cru-cluster-template/component.js +++ b/lib/shared/addon/components/cru-cluster-template/component.js @@ -6,11 +6,8 @@ import { get, set } from '@ember/object'; import { inject as service } from '@ember/service'; import { alias } from '@ember/object/computed'; import Errors from 'ui/utils/errors'; -import { randomStr } from 'shared/utils/util'; import { reject } from 'rsvp'; - - export default Component.extend(ViewNewEdit, ChildHook, { globalStore: service(), router: service(), @@ -36,12 +33,6 @@ export default Component.extend(ViewNewEdit, ChildHook, { this._super(...arguments); set(this, 'originalCluster', get(this, 'clusterTemplateRevision.clusterConfig').clone()); - - let { clusterTemplateRevision } = this; - - if (!clusterTemplateRevision.name) { - set(clusterTemplateRevision, 'name', `revision-${ randomStr(8, 8, 'loweralpha') }`); - } }, actions: { From 4b9fa1742546fb31fdc4878937e2d5032fee7cee Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Fri, 2 Aug 2019 13:48:14 -0700 Subject: [PATCH 10/11] split cluster template/revisions into sep dropdowns cluster create rancher/rancher#21891 --- .../cluster-driver/driver-rke/component.js | 116 ++++++++++-------- .../cluster-driver/driver-rke/template.hbs | 31 +++-- translations/en-us.yaml | 5 +- 3 files changed, 89 insertions(+), 63 deletions(-) diff --git a/lib/shared/addon/components/cluster-driver/driver-rke/component.js b/lib/shared/addon/components/cluster-driver/driver-rke/component.js index d0354e684..78e153ee4 100644 --- a/lib/shared/addon/components/cluster-driver/driver-rke/component.js +++ b/lib/shared/addon/components/cluster-driver/driver-rke/component.js @@ -67,62 +67,63 @@ const { } = C; export default InputTextFile.extend(ManageLabels, ClusterDriver, { - globalStore: service(), - settings: service(), - growl: service(), - intl: service(), - clusterTemplates: service(), - access: service(), - router: service(), + globalStore: service(), + settings: service(), + growl: service(), + intl: service(), + clusterTemplates: service(), + access: service(), + router: service(), layout, - authChoices: AUTHCHOICES, - ingressChoices: INGRESSCHOICES, - availableStrategies: AVAILABLE_STRATEGIES, - ingornedRkeOverrides: CLUSTER_TEMPLATE_IGNORED_OVERRIDES, + authChoices: AUTHCHOICES, + ingressChoices: INGRESSCHOICES, + availableStrategies: AVAILABLE_STRATEGIES, + ingornedRkeOverrides: CLUSTER_TEMPLATE_IGNORED_OVERRIDES, - configField: 'rancherKubernetesEngineConfig', - registry: 'default', - accept: '.yml, .yaml', - backupStrategy: 'local', - overrideCreatLabel: null, - loading: false, - pasteOrUpload: false, - model: null, - initialVersion: null, - registryUrl: null, - registryUser: null, - registryPass: null, - clusterOptErrors: null, - nodeNameErrors: null, + configField: 'rancherKubernetesEngineConfig', + registry: 'default', + accept: '.yml, .yaml', + backupStrategy: 'local', + overrideCreatLabel: null, + loading: false, + pasteOrUpload: false, + model: null, + initialVersion: null, + registryUrl: null, + registryUser: null, + registryPass: null, + clusterOptErrors: null, + nodeNameErrors: null, - existingNodes: null, - initialNodeCounts: null, - step: 1, - token: null, - taints: null, - labels: null, - etcd: false, - controlplane: false, - worker: true, - defaultDockerRootDir: null, - nodePoolErrors: null, + existingNodes: null, + initialNodeCounts: null, + step: 1, + token: null, + taints: null, + labels: null, + etcd: false, + controlplane: false, + worker: true, + defaultDockerRootDir: null, + nodePoolErrors: null, - windowsEnable: false, - isLinux: true, - weaveCustomPassword: false, - clusterTemplateCreate: false, - clusterTemplateQuestions: null, - forceExpandOnInit: false, - forceExpandAll: false, - applyClusterTemplate: null, - useClusterTemplate: false, - clusterTemplateRevisionId: null, - clusterTemplatesEnforced: false, - isNew: equal('mode', 'new'), - isEdit: equal('mode', 'edit'), - notView: or('isNew', 'isEdit'), - clusterState: alias('model.originalCluster.state'), + windowsEnable: false, + isLinux: true, + weaveCustomPassword: false, + clusterTemplateCreate: false, + clusterTemplateQuestions: null, + forceExpandOnInit: false, + forceExpandAll: false, + applyClusterTemplate: null, + useClusterTemplate: false, + clusterTemplateRevisionId: null, + clusterTemplatesEnforced: false, + selectedClusterTemplateId: null, + isNew: equal('mode', 'new'), + isEdit: equal('mode', 'edit'), + notView: or('isNew', 'isEdit'), + clusterState: alias('model.originalCluster.state'), // Custom stuff isCustom: equal('nodeWhich', 'custom'), @@ -134,8 +135,9 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { if (!this.useClusterTemplate && this.clusterTemplateRevisionId) { setProperties(this, { - useClusterTemplate: true, - forceExpandOnInit: true, + useClusterTemplate: true, + forceExpandOnInit: true, + selectedClusterTemplateId: this.model.clusterTemplateRevision.clusterTemplateId, }) } @@ -414,6 +416,14 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { return [...(errors || []), ...(clusterErrors || []), ...(clusterOptErrors || []), ...(otherErrors || [])]; }), + filteredClusterTemplates: computed('model.clusterTemplates.@each.{id,state,name,members}', function() { + return get(this, 'model.clusterTemplates'); + }), + + filteredTemplateRevisions: computed('selectedClusterTemplateId', 'model.clusterTemplateRevisions.@each.{id,state,name,members}', function() { + return get(this, 'model.clusterTemplateRevisions').filterBy('enabled').filterBy('clusterTemplateId', this.selectedClusterTemplateId); + }), + allTemplates: computed('model.clusterTemplates.[]', 'model.clusterTemplateRevisions.[]', function() { const remapped = []; let { clusterTemplates, clusterTemplateRevisions } = this.model; diff --git a/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs b/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs index b0d790c97..a44209df2 100644 --- a/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs +++ b/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs @@ -33,7 +33,7 @@
{{#if (or (or model.clusterTemplateRevisions model.clusterTemplateRevision) clusterTemplatesEnforced)}} -
+
- {{#if useClusterTemplate}} +
+ {{#if useClusterTemplate}} +
{{new-select id="input-cluster-template-select" classNames="form-control" - optionValuePath="clusterTemplateRevisionId" - optionLabelPath="clusterTemplateRevisionId" - optionGroupPath="clusterTemplateName" - content=allTemplates - value=clusterTemplateRevisionId + optionValuePath="id" + optionLabelPath="name" + content=filteredClusterTemplates + value=selectedClusterTemplateId prompt=(t "clusterNew.rke.clustersSelectTemplate.select.prompt") localizedPrompt=true }} - {{/if}} -
+
+
+ {{new-select + classNames="form-control" + optionValuePath="id" + optionLabelPath="name" + content=filteredTemplateRevisions + value=clusterTemplateRevisionId + disabled=(not selectedClusterTemplateId) + prompt=(t "clusterNew.rke.clustersSelectTemplateRevision.select.prompt") + localizedPrompt=true + }} +
+ {{/if}} {{/if}}
diff --git a/translations/en-us.yaml b/translations/en-us.yaml index 8f16c3678..2e6dee51c 100644 --- a/translations/en-us.yaml +++ b/translations/en-us.yaml @@ -3190,10 +3190,13 @@ clusterNew: label: EIP Share Type rke: clustersSelectTemplate: - label: "Use an existing cluster template" + label: "Use an existing cluster template and revision" select: label: Cluster Templates prompt: Select a cluster template + clustersSelectTemplateRevision: + select: + prompt: Select a cluster template revision etcd: enabled: label: Recurring etcd Snapshot Enabled From 464acc46489c6d58e511f01eaf8a9c0f247f7aa5 Mon Sep 17 00:00:00 2001 From: Westly Wright Date: Fri, 2 Aug 2019 14:41:34 -0700 Subject: [PATCH 11/11] refactor new required error check into own function --- .../cluster-driver/driver-rke/component.js | 53 ++++++++++--------- .../cluster-driver/driver-rke/template.hbs | 2 +- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/lib/shared/addon/components/cluster-driver/driver-rke/component.js b/lib/shared/addon/components/cluster-driver/driver-rke/component.js index 78e153ee4..5de78426b 100644 --- a/lib/shared/addon/components/cluster-driver/driver-rke/component.js +++ b/lib/shared/addon/components/cluster-driver/driver-rke/component.js @@ -779,11 +779,11 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { willSave() { const { + applyClusterTemplate, cluster, configField: field, - intl, } = this; - let ok = true; + let ok = true; this.checkKubernetesVersionSemVer(); @@ -806,35 +806,26 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { ok = this.validate(); if (ok) { - if (typeOf(cluster.clearProvidersExcept) === 'function' || this.applyClusterTemplate && typeOf(cluster.buildClusterAnswersFromConfig) === 'function') { - if (this.applyClusterTemplate) { + if (typeOf(cluster.clearProvidersExcept) === 'function' || applyClusterTemplate && typeOf(this.buildClusterAnswersFromConfig) === 'function') { + if (applyClusterTemplate) { let questions = get(this, 'model.clusterTemplateRevision.questions') || []; - let required = questions.filterBy('required', true); - // need to add overrides + user entry to answers on cluster, drop rkeconfig - let answers = []; - let errors = []; + let answers = []; if (questions.length > 0) { - answers = this.buildClusterAnswersFromConfig(cluster, get(this, 'model.clusterTemplateRevision.questions')) + answers = this.buildClusterAnswersFromConfig(cluster, questions); - if (required.length > 0) { - required.forEach((rq) => { - if (!answers[rq.variable]) { - errors.push(intl.t('validation.required', { key: rq.variable })); - } - }) + let errors = this.checkRequiredQuestionsHaveAnswers(questions, answers); + + if (isEmpty(errors)) { + set(cluster, 'answers', { values: answers }); + + this.cluster.clearConfigFieldsForClusterTemplate(); + } else { + set(this, 'errors', errors); + + return false; } } - - if (errors.length > 0 ) { - set(this, 'errors', errors); - - return false; - } - - this.cluster.clearConfigFieldsForClusterTemplate(); - - set(cluster, 'answers', { values: answers }); } else { cluster.clearProvidersExcept(field); } @@ -845,7 +836,19 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, { }, checkRequiredQuestionsHaveAnswers(questions, answers) { + const { intl } = this; + const required = questions.filterBy('required', true); + const errors = []; + if (questions.length > 0 && required.length > 0) { + required.forEach((rq) => { + if (!answers[rq.variable]) { + errors.push(intl.t('validation.required', { key: rq.variable })); + } + }) + } + + return errors; }, validate() { diff --git a/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs b/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs index a44209df2..56f9dbad1 100644 --- a/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs +++ b/lib/shared/addon/components/cluster-driver/driver-rke/template.hbs @@ -40,7 +40,7 @@ type="checkbox" checked=useClusterTemplate id="use-existing-cluster-template" - disabled=(or clusterTemplatesEnforced pasteOrUpload) + disabled=(or isEdit (or clusterTemplatesEnforced pasteOrUpload)) }} {{t "clusterNew.rke.clustersSelectTemplate.label"}}