mirror of https://github.com/rancher/ui.git
Merge pull request #3184 from westlywright/cluster.templates.bugs
Cluster Templates
This commit is contained in:
commit
dde3c3edbc
|
|
@ -1,7 +1,7 @@
|
||||||
import Resource from '@rancher/ember-api-store/models/resource';
|
import Resource from '@rancher/ember-api-store/models/resource';
|
||||||
import { reference } from '@rancher/ember-api-store/utils/denormalize';
|
import { reference } from '@rancher/ember-api-store/utils/denormalize';
|
||||||
import { inject as service } from '@ember/service';
|
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';
|
import { alias } from '@ember/object/computed';
|
||||||
|
|
||||||
export default Resource.extend({
|
export default Resource.extend({
|
||||||
|
|
@ -114,12 +114,14 @@ export default Resource.extend({
|
||||||
validationErrors() {
|
validationErrors() {
|
||||||
let errors = [];
|
let errors = [];
|
||||||
|
|
||||||
|
if (!get(this, 'name')) {
|
||||||
|
errors.push('Revision name is required');
|
||||||
|
}
|
||||||
|
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
errors = this._super(...arguments);
|
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
"ember-auto-import": "*",
|
"ember-auto-import": "*",
|
||||||
"ember-cli-htmlbars": "*",
|
"ember-cli-htmlbars": "*",
|
||||||
"ember-href-to": "*",
|
"ember-href-to": "*",
|
||||||
"ember-cli-babel": "*"
|
"ember-cli-babel": "*",
|
||||||
|
"ember-deep-set": "*"
|
||||||
},
|
},
|
||||||
"ember-addon": {
|
"ember-addon": {
|
||||||
"paths": [
|
"paths": [
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import ManageLabels from 'shared/mixins/manage-labels';
|
||||||
import { typeOf } from '@ember/utils';
|
import { typeOf } from '@ember/utils';
|
||||||
import Semver, { major, minor } from 'semver';
|
import Semver, { major, minor } from 'semver';
|
||||||
import { on } from '@ember/object/evented';
|
import { on } from '@ember/object/evented';
|
||||||
|
import deepSet from 'ember-deep-set';
|
||||||
|
|
||||||
const EXCLUDED_KEYS = ['extra_args'];
|
const EXCLUDED_KEYS = ['extra_args'];
|
||||||
|
|
||||||
|
|
@ -66,62 +67,63 @@ const {
|
||||||
} = C;
|
} = C;
|
||||||
|
|
||||||
export default InputTextFile.extend(ManageLabels, ClusterDriver, {
|
export default InputTextFile.extend(ManageLabels, ClusterDriver, {
|
||||||
globalStore: service(),
|
globalStore: service(),
|
||||||
settings: service(),
|
settings: service(),
|
||||||
growl: service(),
|
growl: service(),
|
||||||
intl: service(),
|
intl: service(),
|
||||||
clusterTemplates: service(),
|
clusterTemplates: service(),
|
||||||
access: service(),
|
access: service(),
|
||||||
router: service(),
|
router: service(),
|
||||||
|
|
||||||
layout,
|
layout,
|
||||||
authChoices: AUTHCHOICES,
|
authChoices: AUTHCHOICES,
|
||||||
ingressChoices: INGRESSCHOICES,
|
ingressChoices: INGRESSCHOICES,
|
||||||
availableStrategies: AVAILABLE_STRATEGIES,
|
availableStrategies: AVAILABLE_STRATEGIES,
|
||||||
ingornedRkeOverrides: CLUSTER_TEMPLATE_IGNORED_OVERRIDES,
|
ingornedRkeOverrides: CLUSTER_TEMPLATE_IGNORED_OVERRIDES,
|
||||||
|
|
||||||
configField: 'rancherKubernetesEngineConfig',
|
configField: 'rancherKubernetesEngineConfig',
|
||||||
registry: 'default',
|
registry: 'default',
|
||||||
accept: '.yml, .yaml',
|
accept: '.yml, .yaml',
|
||||||
backupStrategy: 'local',
|
backupStrategy: 'local',
|
||||||
overrideCreatLabel: null,
|
overrideCreatLabel: null,
|
||||||
loading: false,
|
loading: false,
|
||||||
pasteOrUpload: false,
|
pasteOrUpload: false,
|
||||||
model: null,
|
model: null,
|
||||||
initialVersion: null,
|
initialVersion: null,
|
||||||
registryUrl: null,
|
registryUrl: null,
|
||||||
registryUser: null,
|
registryUser: null,
|
||||||
registryPass: null,
|
registryPass: null,
|
||||||
clusterOptErrors: null,
|
clusterOptErrors: null,
|
||||||
nodeNameErrors: null,
|
nodeNameErrors: null,
|
||||||
|
|
||||||
existingNodes: null,
|
existingNodes: null,
|
||||||
initialNodeCounts: null,
|
initialNodeCounts: null,
|
||||||
step: 1,
|
step: 1,
|
||||||
token: null,
|
token: null,
|
||||||
taints: null,
|
taints: null,
|
||||||
labels: null,
|
labels: null,
|
||||||
etcd: false,
|
etcd: false,
|
||||||
controlplane: false,
|
controlplane: false,
|
||||||
worker: true,
|
worker: true,
|
||||||
defaultDockerRootDir: null,
|
defaultDockerRootDir: null,
|
||||||
nodePoolErrors: null,
|
nodePoolErrors: null,
|
||||||
|
|
||||||
windowsEnable: false,
|
windowsEnable: false,
|
||||||
isLinux: true,
|
isLinux: true,
|
||||||
weaveCustomPassword: false,
|
weaveCustomPassword: false,
|
||||||
clusterTemplateCreate: false,
|
clusterTemplateCreate: false,
|
||||||
clusterTemplateQuestions: null,
|
clusterTemplateQuestions: null,
|
||||||
forceExpandOnInit: false,
|
forceExpandOnInit: false,
|
||||||
forceExpandAll: false,
|
forceExpandAll: false,
|
||||||
applyClusterTemplate: null,
|
applyClusterTemplate: null,
|
||||||
useClusterTemplate: false,
|
useClusterTemplate: false,
|
||||||
clusterTemplateRevisionId: null,
|
clusterTemplateRevisionId: null,
|
||||||
clusterTemplatesEnforced: false,
|
clusterTemplatesEnforced: false,
|
||||||
isNew: equal('mode', 'new'),
|
selectedClusterTemplateId: null,
|
||||||
isEdit: equal('mode', 'edit'),
|
isNew: equal('mode', 'new'),
|
||||||
notView: or('isNew', 'isEdit'),
|
isEdit: equal('mode', 'edit'),
|
||||||
clusterState: alias('model.originalCluster.state'),
|
notView: or('isNew', 'isEdit'),
|
||||||
|
clusterState: alias('model.originalCluster.state'),
|
||||||
|
|
||||||
// Custom stuff
|
// Custom stuff
|
||||||
isCustom: equal('nodeWhich', 'custom'),
|
isCustom: equal('nodeWhich', 'custom'),
|
||||||
|
|
@ -133,8 +135,9 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, {
|
||||||
|
|
||||||
if (!this.useClusterTemplate && this.clusterTemplateRevisionId) {
|
if (!this.useClusterTemplate && this.clusterTemplateRevisionId) {
|
||||||
setProperties(this, {
|
setProperties(this, {
|
||||||
useClusterTemplate: true,
|
useClusterTemplate: true,
|
||||||
forceExpandOnInit: true,
|
forceExpandOnInit: true,
|
||||||
|
selectedClusterTemplateId: this.model.clusterTemplateRevision.clusterTemplateId,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -413,6 +416,14 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, {
|
||||||
return [...(errors || []), ...(clusterErrors || []), ...(clusterOptErrors || []), ...(otherErrors || [])];
|
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() {
|
allTemplates: computed('model.clusterTemplates.[]', 'model.clusterTemplateRevisions.[]', function() {
|
||||||
const remapped = [];
|
const remapped = [];
|
||||||
let { clusterTemplates, clusterTemplateRevisions } = this.model;
|
let { clusterTemplates, clusterTemplateRevisions } = this.model;
|
||||||
|
|
@ -767,7 +778,12 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, {
|
||||||
},
|
},
|
||||||
|
|
||||||
willSave() {
|
willSave() {
|
||||||
const { cluster, configField: field } = this;
|
const {
|
||||||
|
applyClusterTemplate,
|
||||||
|
cluster,
|
||||||
|
configField: field,
|
||||||
|
} = this;
|
||||||
|
let ok = true;
|
||||||
|
|
||||||
this.checkKubernetesVersionSemVer();
|
this.checkKubernetesVersionSemVer();
|
||||||
|
|
||||||
|
|
@ -779,19 +795,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, 'localClusterAuthEndpoint')) {
|
||||||
if (!get(cluster, 'rancherKubernetesEngineConfig') || isEmpty(get(cluster, 'rancherKubernetesEngineConfig'))) {
|
if (!get(cluster, 'rancherKubernetesEngineConfig') || isEmpty(get(cluster, 'rancherKubernetesEngineConfig'))) {
|
||||||
delete cluster.localClusterAuthEndpoint;
|
delete cluster.localClusterAuthEndpoint;
|
||||||
|
|
@ -800,22 +803,79 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, {
|
||||||
|
|
||||||
set(this, 'errors', null);
|
set(this, 'errors', null);
|
||||||
|
|
||||||
// TODO
|
ok = this.validate();
|
||||||
if (this.applyClusterTemplate || this.clusterTemplateCreate) {
|
|
||||||
return true;
|
if (ok) {
|
||||||
} else {
|
if (typeOf(cluster.clearProvidersExcept) === 'function' || applyClusterTemplate && typeOf(this.buildClusterAnswersFromConfig) === 'function') {
|
||||||
return this.validate();
|
if (applyClusterTemplate) {
|
||||||
|
let questions = get(this, 'model.clusterTemplateRevision.questions') || [];
|
||||||
|
let answers = [];
|
||||||
|
|
||||||
|
if (questions.length > 0) {
|
||||||
|
answers = this.buildClusterAnswersFromConfig(cluster, questions);
|
||||||
|
|
||||||
|
let errors = this.checkRequiredQuestionsHaveAnswers(questions, answers);
|
||||||
|
|
||||||
|
if (isEmpty(errors)) {
|
||||||
|
set(cluster, 'answers', { values: answers });
|
||||||
|
|
||||||
|
this.cluster.clearConfigFieldsForClusterTemplate();
|
||||||
|
} else {
|
||||||
|
set(this, 'errors', errors);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cluster.clearProvidersExcept(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
},
|
||||||
|
|
||||||
|
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() {
|
validate() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
let errors = [];
|
let errors = [];
|
||||||
let config = get(this, `config`);
|
let { config, intl } = this;
|
||||||
|
|
||||||
if ( !get(this, 'isCustom') ) {
|
|
||||||
errors.pushObjects(get(this, 'nodePoolErrors'));
|
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') &&
|
if ( get(config, 'services.kubeApi.podSecurityPolicy') &&
|
||||||
|
|
@ -833,18 +893,6 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, {
|
||||||
|
|
||||||
const clusterOptErrors = get(this, 'clusterOptErrors') || [];
|
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);
|
set(this, 'errors', errors);
|
||||||
|
|
||||||
return errors.length === 0 && clusterOptErrors.length === 0;
|
return errors.length === 0 && clusterOptErrors.length === 0;
|
||||||
|
|
@ -922,29 +970,33 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, {
|
||||||
loadToken() {
|
loadToken() {
|
||||||
const cluster = get(this, 'primaryResource');
|
const cluster = get(this, 'primaryResource');
|
||||||
|
|
||||||
setProperties(this, {
|
if (cluster.getOrCreateToken) {
|
||||||
step: 2,
|
|
||||||
loading: true
|
|
||||||
});
|
|
||||||
|
|
||||||
return cluster.getOrCreateToken().then((token) => {
|
|
||||||
if ( this.isDestroyed || this.isDestroying ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setProperties(this, {
|
setProperties(this, {
|
||||||
token,
|
step: 2,
|
||||||
loading: false
|
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) {
|
findExcludedKeys(resourceFields) {
|
||||||
|
|
@ -1268,7 +1320,7 @@ export default InputTextFile.extend(ManageLabels, ClusterDriver, {
|
||||||
let path = question.variable;
|
let path = question.variable;
|
||||||
|
|
||||||
if (!question.variable.includes('uiOverride') && question.default) {
|
if (!question.variable.includes('uiOverride') && question.default) {
|
||||||
set(primaryResource, path, question.default);
|
deepSet(primaryResource, path, question.default);
|
||||||
}
|
}
|
||||||
|
|
||||||
set(question, 'primaryResource', primaryResource);
|
set(question, 'primaryResource', primaryResource);
|
||||||
|
|
|
||||||
|
|
@ -33,31 +33,44 @@
|
||||||
<section class="cluster-template-select mb-5">
|
<section class="cluster-template-select mb-5">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{#if (or (or model.clusterTemplateRevisions model.clusterTemplateRevision) clusterTemplatesEnforced)}}
|
{{#if (or (or model.clusterTemplateRevisions model.clusterTemplateRevision) clusterTemplatesEnforced)}}
|
||||||
<div class="col span-6">
|
<div>
|
||||||
<label class="acc-label" for="use-existing-cluster-template">
|
<label class="acc-label" for="use-existing-cluster-template">
|
||||||
{{input
|
{{input
|
||||||
class="input-lg"
|
class="input-lg"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked=useClusterTemplate
|
checked=useClusterTemplate
|
||||||
id="use-existing-cluster-template"
|
id="use-existing-cluster-template"
|
||||||
disabled=(or clusterTemplatesEnforced pasteOrUpload)
|
disabled=(or isEdit (or clusterTemplatesEnforced pasteOrUpload))
|
||||||
}}
|
}}
|
||||||
{{t "clusterNew.rke.clustersSelectTemplate.label"}}
|
{{t "clusterNew.rke.clustersSelectTemplate.label"}}
|
||||||
</label>
|
</label>
|
||||||
{{#if useClusterTemplate}}
|
</div>
|
||||||
|
{{#if useClusterTemplate}}
|
||||||
|
<div class="col span-6">
|
||||||
{{new-select
|
{{new-select
|
||||||
id="input-cluster-template-select"
|
id="input-cluster-template-select"
|
||||||
classNames="form-control"
|
classNames="form-control"
|
||||||
optionValuePath="clusterTemplateRevisionId"
|
optionValuePath="id"
|
||||||
optionLabelPath="clusterTemplateRevisionId"
|
optionLabelPath="name"
|
||||||
optionGroupPath="clusterTemplateName"
|
content=filteredClusterTemplates
|
||||||
content=allTemplates
|
value=selectedClusterTemplateId
|
||||||
value=clusterTemplateRevisionId
|
|
||||||
prompt=(t "clusterNew.rke.clustersSelectTemplate.select.prompt")
|
prompt=(t "clusterNew.rke.clustersSelectTemplate.select.prompt")
|
||||||
localizedPrompt=true
|
localizedPrompt=true
|
||||||
}}
|
}}
|
||||||
{{/if}}
|
</div>
|
||||||
</div>
|
<div class="col span-6">
|
||||||
|
{{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
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { alias } from '@ember/object/computed';
|
||||||
import { isEmpty } from '@ember/utils';
|
import { isEmpty } from '@ember/utils';
|
||||||
import C from 'ui/utils/constants';
|
import C from 'ui/utils/constants';
|
||||||
import { azure as AzureInfo } from './cloud-provider-info';
|
import { azure as AzureInfo } from './cloud-provider-info';
|
||||||
|
import { next } from '@ember/runloop';
|
||||||
|
|
||||||
const azureDefaults = C.AZURE_DEFAULTS;
|
const azureDefaults = C.AZURE_DEFAULTS;
|
||||||
const GENERIC_PATH = 'cluster.rancherKubernetesEngineConfig.cloudProvider.cloudConfig';
|
const GENERIC_PATH = 'cluster.rancherKubernetesEngineConfig.cloudProvider.cloudConfig';
|
||||||
|
|
@ -110,30 +111,47 @@ export default Component.extend({
|
||||||
'clusterTemplateCreate',
|
'clusterTemplateCreate',
|
||||||
'applyClusterTemplate',
|
'applyClusterTemplate',
|
||||||
'clusterTemplateRevision.questions',
|
'clusterTemplateRevision.questions',
|
||||||
|
'clusterTemplateRevision.id',
|
||||||
function() {
|
function() {
|
||||||
let { clusterTemplateRevision, applyClusterTemplate } = this;
|
let { clusterTemplateRevision, applyClusterTemplate } = this;
|
||||||
|
|
||||||
if (applyClusterTemplate && clusterTemplateRevision && clusterTemplateRevision.questions) {
|
if (applyClusterTemplate && clusterTemplateRevision) {
|
||||||
let found = clusterTemplateRevision.questions.filter((ctr) => {
|
if (clusterTemplateRevision.questions) {
|
||||||
return ctr.variable.includes('rancherKubernetesEngineConfig.cloudProvider');
|
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;
|
return false;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
isCreateClusterOrClusterTemplate: computed('', function() {
|
isCreateClusterOrClusterTemplate: computed('applyClusterTemplate', function() {
|
||||||
const { clusterTemplateCreate, applyClusterTemplate } = this;
|
const { applyClusterTemplate } = this;
|
||||||
|
|
||||||
if (!clusterTemplateCreate && !applyClusterTemplate) {
|
if (applyClusterTemplate) {
|
||||||
return true;
|
return false;
|
||||||
} else if (clusterTemplateCreate) {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
checkDefaults(record) {
|
checkDefaults(record) {
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@ export default Component.extend({
|
||||||
ignoreFields,
|
ignoreFields,
|
||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
allQuestions = allQuestions.slice();
|
allQuestions = ( allQuestions || []).slice();
|
||||||
|
|
||||||
allQuestions.forEach((q) => {
|
allQuestions.forEach((q) => {
|
||||||
if (ignoreFields.includes(q.variable)) {
|
if (ignoreFields.includes(q.variable)) {
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,8 @@ import { get, set } from '@ember/object';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import { alias } from '@ember/object/computed';
|
import { alias } from '@ember/object/computed';
|
||||||
import Errors from 'ui/utils/errors';
|
import Errors from 'ui/utils/errors';
|
||||||
import { randomStr } from 'shared/utils/util';
|
|
||||||
import { reject } from 'rsvp';
|
import { reject } from 'rsvp';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default Component.extend(ViewNewEdit, ChildHook, {
|
export default Component.extend(ViewNewEdit, ChildHook, {
|
||||||
globalStore: service(),
|
globalStore: service(),
|
||||||
router: service(),
|
router: service(),
|
||||||
|
|
@ -36,12 +33,6 @@ export default Component.extend(ViewNewEdit, ChildHook, {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
set(this, 'originalCluster', get(this, 'clusterTemplateRevision.clusterConfig').clone());
|
set(this, 'originalCluster', get(this, 'clusterTemplateRevision.clusterConfig').clone());
|
||||||
|
|
||||||
let { clusterTemplateRevision } = this;
|
|
||||||
|
|
||||||
if (!clusterTemplateRevision.name) {
|
|
||||||
set(clusterTemplateRevision, 'name', `revision-${ randomStr(8, 8, 'loweralpha') }`);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ export default Component.extend(ViewNewEdit, ChildHook, {
|
||||||
intl: service(),
|
intl: service(),
|
||||||
access: service(),
|
access: service(),
|
||||||
cookies: service(),
|
cookies: service(),
|
||||||
|
router: service(),
|
||||||
|
|
||||||
layout,
|
layout,
|
||||||
step: 1,
|
step: 1,
|
||||||
|
|
@ -28,6 +29,7 @@ export default Component.extend(ViewNewEdit, ChildHook, {
|
||||||
reloadingSchema: false,
|
reloadingSchema: false,
|
||||||
schemaReloaded: false,
|
schemaReloaded: false,
|
||||||
applyClusterTemplate: false,
|
applyClusterTemplate: false,
|
||||||
|
routeLoading: false,
|
||||||
|
|
||||||
showClassicLauncher: false,
|
showClassicLauncher: false,
|
||||||
nodePoolErrors: null,
|
nodePoolErrors: null,
|
||||||
|
|
@ -58,11 +60,26 @@ export default Component.extend(ViewNewEdit, ChildHook, {
|
||||||
if ( isEmpty(get(this, 'cluster.id')) ){
|
if ( isEmpty(get(this, 'cluster.id')) ){
|
||||||
set(this, 'newCluster', true);
|
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: {
|
actions: {
|
||||||
updateFromYaml(newOpts) {
|
updateFromYaml(newOpts) {
|
||||||
this.cluster.replaceWith(newOpts);
|
if (this.isEdit) {
|
||||||
|
this.cluster.merge(newOpts);
|
||||||
|
} else {
|
||||||
|
this.cluster.replaceWith(newOpts);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clickNext() {
|
clickNext() {
|
||||||
|
|
|
||||||
|
|
@ -82,22 +82,24 @@
|
||||||
{{/accordion-list}}
|
{{/accordion-list}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{component driverInfo.driverComponent
|
{{#unless routeLoading}}
|
||||||
applyClusterTemplate=applyClusterTemplate
|
{{component driverInfo.driverComponent
|
||||||
clusterTemplateQuestions=model.clusterTemplateRevision.questions
|
applyClusterTemplate=applyClusterTemplate
|
||||||
clusterTemplateRevisionId=clusterTemplateRevisionId
|
clusterTemplateQuestions=model.clusterTemplateRevision.questions
|
||||||
clusterErrors=errors
|
clusterTemplateRevisionId=clusterTemplateRevisionId
|
||||||
mode=mode
|
clusterErrors=errors
|
||||||
model=model
|
mode=mode
|
||||||
nodePoolErrors=nodePoolErrors
|
model=model
|
||||||
nodeWhich=driverInfo.nodeWhich
|
nodePoolErrors=nodePoolErrors
|
||||||
originalCluster=originalCluster
|
nodeWhich=driverInfo.nodeWhich
|
||||||
otherErrors=memberErrors
|
originalCluster=originalCluster
|
||||||
save=(action "save")
|
otherErrors=memberErrors
|
||||||
close=(action "close")
|
save=(action "save")
|
||||||
registerHook=(action "registerHook")
|
close=(action "close")
|
||||||
updateFromYaml=(action "updateFromYaml")
|
registerHook=(action "registerHook")
|
||||||
}}
|
updateFromYaml=(action "updateFromYaml")
|
||||||
|
}}
|
||||||
|
{{/unless}}
|
||||||
|
|
||||||
{{#if (and isEdit (not provider))}}
|
{{#if (and isEdit (not provider))}}
|
||||||
{{top-errors errors=errors}}
|
{{top-errors errors=errors}}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@ export default Component.extend({
|
||||||
initialVersion,
|
initialVersion,
|
||||||
defaultK8sVersion,
|
defaultK8sVersion,
|
||||||
applyClusterTemplate = false,
|
applyClusterTemplate = false,
|
||||||
clusterTemplateCreate = false,
|
|
||||||
clusterTemplateQuestions = [],
|
clusterTemplateQuestions = [],
|
||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
|
|
@ -70,7 +69,7 @@ export default Component.extend({
|
||||||
|
|
||||||
let maxVersion = maxSatisfying(versions, defaultK8sVersionRange);
|
let maxVersion = maxSatisfying(versions, defaultK8sVersionRange);
|
||||||
|
|
||||||
if (applyClusterTemplate || clusterTemplateCreate) {
|
if ( applyClusterTemplate ) {
|
||||||
var overrideMatch = ( clusterTemplateQuestions || [] ).findBy('variable', 'rancherKubernetesEngineConfig.kubernetesVersion');
|
var overrideMatch = ( clusterTemplateQuestions || [] ).findBy('variable', 'rancherKubernetesEngineConfig.kubernetesVersion');
|
||||||
|
|
||||||
if (overrideMatch) {
|
if (overrideMatch) {
|
||||||
|
|
@ -78,7 +77,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
|
// 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);
|
maxVersion = maxSatisfying(versions, initialVersion);
|
||||||
} else {
|
} else {
|
||||||
supportedVersionsRange = overrideMatch.satisfies;
|
if (overrideMatch.satisfies) {
|
||||||
|
supportedVersionsRange = overrideMatch.satisfies;
|
||||||
|
}
|
||||||
|
|
||||||
maxVersion = maxSatisfying(versions, supportedVersionsRange);
|
maxVersion = maxSatisfying(versions, supportedVersionsRange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,10 @@ export default Mixin.create({
|
||||||
cb(true);
|
cb(true);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
if ( this.isDestroyed || this.isDestroying ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.send('error', err);
|
this.send('error', err);
|
||||||
this.errorSaving(err);
|
this.errorSaving(err);
|
||||||
cb(false);
|
cb(false);
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@
|
||||||
"ember-concurrency": "^0.8.24",
|
"ember-concurrency": "^0.8.24",
|
||||||
"ember-copy": "^1.0.0",
|
"ember-copy": "^1.0.0",
|
||||||
"ember-credit-card": "^2.4.0",
|
"ember-credit-card": "^2.4.0",
|
||||||
|
"ember-deep-set": "^0.2.0",
|
||||||
"ember-drag-drop": "^0.4.7",
|
"ember-drag-drop": "^0.4.7",
|
||||||
"ember-engines": "^0.6.1",
|
"ember-engines": "^0.6.1",
|
||||||
"ember-export-application-global": "^2.0.0",
|
"ember-export-application-global": "^2.0.0",
|
||||||
|
|
|
||||||
|
|
@ -3190,10 +3190,13 @@ clusterNew:
|
||||||
label: EIP Share Type
|
label: EIP Share Type
|
||||||
rke:
|
rke:
|
||||||
clustersSelectTemplate:
|
clustersSelectTemplate:
|
||||||
label: "Use an existing cluster template"
|
label: "Use an existing cluster template and revision"
|
||||||
select:
|
select:
|
||||||
label: Cluster Templates
|
label: Cluster Templates
|
||||||
prompt: Select a cluster template
|
prompt: Select a cluster template
|
||||||
|
clustersSelectTemplateRevision:
|
||||||
|
select:
|
||||||
|
prompt: Select a cluster template revision
|
||||||
etcd:
|
etcd:
|
||||||
enabled:
|
enabled:
|
||||||
label: Recurring etcd Snapshot Enabled
|
label: Recurring etcd Snapshot Enabled
|
||||||
|
|
|
||||||
|
|
@ -4641,6 +4641,13 @@ ember-credit-card@^2.4.0:
|
||||||
ember-cli-htmlbars "2.0.3"
|
ember-cli-htmlbars "2.0.3"
|
||||||
ember-model-validator "^2.18.0"
|
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:
|
ember-diff-attrs@^0.2.1:
|
||||||
version "0.2.2"
|
version "0.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/ember-diff-attrs/-/ember-diff-attrs-0.2.2.tgz#57baf6907957de004d9aff947809dfe78a054b3b"
|
resolved "https://registry.yarnpkg.com/ember-diff-attrs/-/ember-diff-attrs-0.2.2.tgz#57baf6907957de004d9aff947809dfe78a054b3b"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue