mirror of https://github.com/rancher/ui.git
Import YAML
This commit is contained in:
parent
c090c46ccc
commit
e711c0f46d
|
|
@ -15,18 +15,17 @@ export default Controller.extend({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
projectsWithNamespaces: computed('rows.@each.{id,state,clusterId}', 'rows.@each.namespaces', function(){
|
rows: computed('model.namespaces.@each.displayName', 'scope.currentCluster.id', function() {
|
||||||
return get(this, 'rows').filter(p => get(p, 'namespaces.length') > 0);
|
return get(this, 'model.namespaces')
|
||||||
|
.filterBy('displayName');
|
||||||
}),
|
}),
|
||||||
|
|
||||||
projectsWithoutNamespaces: computed('rows.@each.{id,state,clusterId}', 'rows.@each.namespaces', function(){
|
projects: computed('model.projects.@each.clusterId', 'scope.currentCluster.id', function() {
|
||||||
return get(this, 'rows').filter(p => get(p, 'namespaces.length') <= 0);
|
|
||||||
}),
|
|
||||||
|
|
||||||
rows: computed('model.projects.@each.clusterId', function() {
|
|
||||||
return get(this,'model.projects').filterBy('clusterId', get(this,'scope.currentCluster.id'));
|
return get(this,'model.projects').filterBy('clusterId', get(this,'scope.currentCluster.id'));
|
||||||
}),
|
}),
|
||||||
namespaceRows: computed('model.namespaces.@each.{id,state}', function() {
|
|
||||||
return get(this, 'model.namespaces').filterBy('displayName');
|
projectsWithoutNamespaces: computed('projects.@each.{id,state,clusterId}', 'rows.@each.namespaces', function(){
|
||||||
|
return get(this, 'projects').filter(p => get(p, 'namespaces.length') <= 0);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{{#if (eq group 'project')}}
|
{{#if (eq group 'project')}}
|
||||||
{{namespace-table model=model.namespaces prns=projectsWithoutNamespaces}}
|
{{namespace-table model=rows prns=projectsWithoutNamespaces}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{namespace-list model=namespaceRows}}
|
{{namespace-list model=rows}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{{#containers-header showGroup=false}}
|
{{#containers-header showGroup=false}}
|
||||||
{{#link-to "new-stack" classNames="btn btn-sm bg-default mr-10" disabled=(or true (rbac-prevents resource="dnsrecord" scope="project" permission="create"))}}{{t 'nav.containers.importCompose'}}{{/link-to}}
|
<button {{action 'importYaml'}} class="btn btn-sm bg-default mr-10" disabled={{rbac-prevents resource="dnsrecord" scope="project" permission="create"}}>{{t 'nav.containers.importCompose'}}</button>
|
||||||
{{#link-to "authenticated.project.dns.new" scope.currentProject.id class="btn btn-sm bg-primary" disabled=(rbac-prevents resource="dnsrecord" scope="project" permission="create")}}{{t 'nav.containers.addDns'}}{{/link-to}}
|
{{#link-to "authenticated.project.dns.new" scope.currentProject.id class="btn btn-sm bg-primary" disabled=(rbac-prevents resource="dnsrecord" scope="project" permission="create")}}{{t 'nav.containers.addDns'}}{{/link-to}}
|
||||||
{{/containers-header}}
|
{{/containers-header}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ export default Route.extend(Preload,{
|
||||||
access: service(),
|
access: service(),
|
||||||
scope: service(),
|
scope: service(),
|
||||||
globalStore: service(),
|
globalStore: service(),
|
||||||
|
modalService: service('modal'),
|
||||||
|
|
||||||
model(params, transition) {
|
model(params, transition) {
|
||||||
const isPopup = this.controllerFor('application').get('isPopup');
|
const isPopup = this.controllerFor('application').get('isPopup');
|
||||||
|
|
@ -59,6 +60,10 @@ export default Route.extend(Preload,{
|
||||||
this.set('controller.group', neu);
|
this.set('controller.group', neu);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
importYaml() {
|
||||||
|
get(this,'modalService').toggleModal('modal-import', {mode: 'project', projectId: get(this,'scope.currentProject.id')});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
shortcuts: {
|
shortcuts: {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
{{cluster-welcome}}
|
{{cluster-welcome}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#containers-header}}
|
{{#containers-header}}
|
||||||
{{#link-to "new-stack" classNames="btn btn-sm bg-default mr-10" disabled=(or true (rbac-prevents resource="workload" scope="project" permission="create"))}}{{t 'nav.containers.importCompose'}}{{/link-to}}
|
<button {{action 'importYaml'}} class="btn btn-sm bg-default mr-10" disabled={{rbac-prevents resource="workload" scope="project" permission="create"}}>{{t 'nav.containers.importCompose'}}</button>
|
||||||
{{#link-to "containers.run" scope.currentProject.id class="btn btn-sm bg-primary" disabled=(rbac-prevents resource="workload" scope="project" permission="create")}}{{t 'nav.containers.deploy'}}{{/link-to}}
|
{{#link-to "containers.run" scope.currentProject.id class="btn btn-sm bg-primary" disabled=(rbac-prevents resource="workload" scope="project" permission="create")}}{{t 'nav.containers.deploy'}}{{/link-to}}
|
||||||
{{/containers-header}}
|
{{/containers-header}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
{{cluster-welcome}}
|
{{cluster-welcome}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#containers-header showGroup=false}}
|
{{#containers-header showGroup=false}}
|
||||||
{{#link-to "new-stack" classNames="btn btn-sm bg-default mr-10" disabled=(or true (rbac-prevents resource="ingress" scope="project" permission="create"))}}{{t 'nav.containers.importCompose'}}{{/link-to}}
|
<button {{action 'importYaml'}} class="btn btn-sm bg-default mr-10" disabled={{rbac-prevents resource="ingress" scope="project" permission="create"}}>{{t 'nav.containers.importCompose'}}</button>
|
||||||
{{#link-to "ingresses.run" scope.currentProject.id class="btn btn-sm bg-primary" disabled=(rbac-prevents resource="ingress" scope="project" permission="create")}}{{t 'nav.containers.addIngress'}}{{/link-to}}
|
{{#link-to "ingresses.run" scope.currentProject.id class="btn btn-sm bg-primary" disabled=(rbac-prevents resource="ingress" scope="project" permission="create")}}{{t 'nav.containers.addIngress'}}{{/link-to}}
|
||||||
{{/containers-header}}
|
{{/containers-header}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,7 @@ var Principal = Resource.extend({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
logicalType: computed('parsedExternalType', function() {
|
logicalType: computed('parsedExternalType', function() {
|
||||||
switch ( get(this, 'parsedExternalType') )
|
switch ( get(this, 'parsedExternalType') ) {
|
||||||
{
|
|
||||||
case C.PROJECT.TYPE_RANCHER:
|
case C.PROJECT.TYPE_RANCHER:
|
||||||
case C.PROJECT.TYPE_AZURE_USER:
|
case C.PROJECT.TYPE_AZURE_USER:
|
||||||
case C.PROJECT.TYPE_GITHUB_USER:
|
case C.PROJECT.TYPE_GITHUB_USER:
|
||||||
|
|
@ -59,8 +58,7 @@ var Principal = Resource.extend({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
logicalTypeSort: computed('logicalType', function() {
|
logicalTypeSort: computed('logicalType', function() {
|
||||||
switch (get(this, 'logicalType') )
|
switch (get(this, 'logicalType') ) {
|
||||||
{
|
|
||||||
case C.PROJECT.ORG: return 1;
|
case C.PROJECT.ORG: return 1;
|
||||||
case C.PROJECT.TEAM: return 2;
|
case C.PROJECT.TEAM: return 2;
|
||||||
case C.PROJECT.PERSON: return 3;
|
case C.PROJECT.PERSON: return 3;
|
||||||
|
|
@ -71,8 +69,8 @@ var Principal = Resource.extend({
|
||||||
displayType: computed('parsedExternalType','intl.locale', function() {
|
displayType: computed('parsedExternalType','intl.locale', function() {
|
||||||
let key = 'model.identity.displayType.unknown';
|
let key = 'model.identity.displayType.unknown';
|
||||||
let type = get(this, 'parsedExternalType');
|
let type = get(this, 'parsedExternalType');
|
||||||
switch ( type )
|
|
||||||
{
|
switch ( type ) {
|
||||||
case C.PROJECT.TYPE_GITHUB_USER:
|
case C.PROJECT.TYPE_GITHUB_USER:
|
||||||
case C.PROJECT.TYPE_AZURE_USER:
|
case C.PROJECT.TYPE_AZURE_USER:
|
||||||
case C.PROJECT.TYPE_LDAP_USER:
|
case C.PROJECT.TYPE_LDAP_USER:
|
||||||
|
|
@ -81,6 +79,7 @@ var Principal = Resource.extend({
|
||||||
case C.PROJECT.TYPE_ACTIVE_DIRECTORY_USER:
|
case C.PROJECT.TYPE_ACTIVE_DIRECTORY_USER:
|
||||||
key = 'model.identity.displayType.user';
|
key = 'model.identity.displayType.user';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case C.PROJECT.TYPE_AZURE_GROUP:
|
case C.PROJECT.TYPE_AZURE_GROUP:
|
||||||
case C.PROJECT.TYPE_LDAP_GROUP:
|
case C.PROJECT.TYPE_LDAP_GROUP:
|
||||||
case C.PROJECT.TYPE_OPENLDAP_GROUP:
|
case C.PROJECT.TYPE_OPENLDAP_GROUP:
|
||||||
|
|
@ -88,12 +87,15 @@ var Principal = Resource.extend({
|
||||||
case C.PROJECT.TYPE_ACTIVE_DIRECTORY_GROUP:
|
case C.PROJECT.TYPE_ACTIVE_DIRECTORY_GROUP:
|
||||||
key = 'model.identity.displayType.group';
|
key = 'model.identity.displayType.group';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case C.PROJECT.TYPE_GITHUB_TEAM:
|
case C.PROJECT.TYPE_GITHUB_TEAM:
|
||||||
key = 'model.identity.displayType.team';
|
key = 'model.identity.displayType.team';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case C.PROJECT.TYPE_GITHUB_ORG:
|
case C.PROJECT.TYPE_GITHUB_ORG:
|
||||||
key = 'model.identity.displayType.org';
|
key = 'model.identity.displayType.org';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case C.PROJECT.TYPE_RANCHER:
|
case C.PROJECT.TYPE_RANCHER:
|
||||||
key = 'model.identity.displayType.localUser';
|
key = 'model.identity.displayType.localUser';
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
import Controller from '@ember/controller';
|
|
||||||
import NewOrEdit from 'ui/mixins/new-or-edit';
|
|
||||||
|
|
||||||
export default Controller.extend(NewOrEdit, {
|
|
||||||
error: null,
|
|
||||||
editing: false,
|
|
||||||
compose: null,
|
|
||||||
files: null,
|
|
||||||
answers: null,
|
|
||||||
allStacks: null,
|
|
||||||
init() {
|
|
||||||
this._super(...arguments);
|
|
||||||
this.set('allStacks', this.get('store').all('stack'));
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
addTag(tag) {
|
|
||||||
let neu = this.get('model.tags')||[];
|
|
||||||
neu.addObject(tag);
|
|
||||||
this.set('model.tags', neu);
|
|
||||||
},
|
|
||||||
|
|
||||||
answersChanged(answers) {
|
|
||||||
this.set('primaryResource.answers', answers);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
willSave() {
|
|
||||||
let outFiles = {};
|
|
||||||
|
|
||||||
let userFiles = this.get('files')||[];
|
|
||||||
|
|
||||||
Object.keys(userFiles).forEach((key) => {
|
|
||||||
let val = userFiles[key];
|
|
||||||
if ( key && val ) {
|
|
||||||
outFiles[key] = val;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.set('primaryResource.templates', outFiles);
|
|
||||||
return this._super(...arguments);
|
|
||||||
},
|
|
||||||
|
|
||||||
doneSaving: function() {
|
|
||||||
return this.transitionToRoute('stack', this.get('primaryResource.id'));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import Route from '@ember/routing/route';
|
|
||||||
|
|
||||||
export default Route.extend({
|
|
||||||
model() {
|
|
||||||
var stack = this.get('store').createRecord({
|
|
||||||
type: 'stack',
|
|
||||||
templates: {
|
|
||||||
'compose.yml': ''
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return stack;
|
|
||||||
},
|
|
||||||
|
|
||||||
setupController(controller, model) {
|
|
||||||
controller.set('originalModel',null);
|
|
||||||
controller.set('model', model);
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
cancel() {
|
|
||||||
this.goToPrevious();
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
<section class="header clearfix">
|
|
||||||
<h1>{{t 'newStack.header'}}</h1>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
{{form-name-description
|
|
||||||
model=primaryResource
|
|
||||||
namePlaceholder="newStack.name.placeholder"
|
|
||||||
descriptionPlaceholder="newStack.description.placeholder"
|
|
||||||
}}
|
|
||||||
|
|
||||||
{{input-files
|
|
||||||
accept=".yml, .yaml"
|
|
||||||
initialFiles=primaryResource.templates
|
|
||||||
changed=(action (mut files))
|
|
||||||
header='newStack.files.label'
|
|
||||||
addActionLabel='newStack.files.addActionLabel'
|
|
||||||
uploadActionLabel='newStack.files.uploadActionLabel'
|
|
||||||
namePlaceholder='newStack.files.namePlaceholder'
|
|
||||||
valuePlaceholder='newStack.files.valuePlaceholder'
|
|
||||||
protipLabel='newStack.files.protipLabel'
|
|
||||||
}}
|
|
||||||
|
|
||||||
{{#advanced-section}}
|
|
||||||
<hr class="mt-20 mb-20"/>
|
|
||||||
|
|
||||||
<div class="box mt-20">
|
|
||||||
{{form-key-value
|
|
||||||
header=(t 'newStack.answers.label')
|
|
||||||
changed=(action "answersChanged")
|
|
||||||
allowMultilineValue=true
|
|
||||||
addActionLabel="newStack.answers.addActionLabel"
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
{{/advanced-section}}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{{top-errors errors=errors}}
|
|
||||||
{{save-cancel save="save" cancel="cancel"}}
|
|
||||||
|
|
@ -144,7 +144,6 @@ Router.map(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route('workload', {path: '/workload/:workload_id', resetNamespace: true});
|
this.route('workload', {path: '/workload/:workload_id', resetNamespace: true});
|
||||||
this.route('new-stack', {path: '/import-yaml', resetNamespace: true});
|
|
||||||
|
|
||||||
|
|
||||||
// Catalog
|
// Catalog
|
||||||
|
|
|
||||||
|
|
@ -51,3 +51,7 @@ pre {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.CodeMirror-scroll {
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -317,8 +317,3 @@
|
||||||
.text-line-through{
|
.text-line-through{
|
||||||
text-decoration: line-through !important;
|
text-decoration: line-through !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CodeMirror{
|
|
||||||
height: auto;
|
|
||||||
min-height: 300px;
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{{#containers-header showGroup=false}}
|
{{#containers-header showGroup=false}}
|
||||||
{{#link-to "new-stack" classNames="btn btn-sm bg-default mr-10" disabled=(or true (rbac-prevents resource="ingress" scope="project" permission="create"))}}{{t 'nav.containers.importCompose'}}{{/link-to}}
|
<button {{action 'importYaml'}} class="btn btn-sm bg-default mr-10" disabled={{rbac-prevents resource="persistenvolumeclaim" scope="project" permission="create"}}>{{t 'nav.containers.importCompose'}}</button>
|
||||||
{{#link-to "volumes.new" class="btn btn-sm bg-primary"}}{{t 'nav.containers.addVolume'}}{{/link-to}}
|
{{#link-to "volumes.new" class="btn btn-sm bg-primary"}}{{t 'nav.containers.addVolume'}}{{/link-to}}
|
||||||
{{/containers-header}}
|
{{/containers-header}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ export default Component.extend(ViewNewEdit, ChildHook, {
|
||||||
|
|
||||||
didSave() {
|
didSave() {
|
||||||
const originalCluster = get(this, 'cluster');
|
const originalCluster = get(this, 'cluster');
|
||||||
return originalCluster.waitForCondition('BackingNamespaceCreated').then(() => {
|
return originalCluster.waitForCondition('InitialRolesPopulated').then(() => {
|
||||||
return this.applyHooks().then(() => {
|
return this.applyHooks().then(() => {
|
||||||
const clone = originalCluster.clone();
|
const clone = originalCluster.clone();
|
||||||
set(this, 'cluster', clone);
|
set(this, 'cluster', clone);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ export default Component.extend({
|
||||||
intl: service(),
|
intl: service(),
|
||||||
scope: service(),
|
scope: service(),
|
||||||
|
|
||||||
|
createLabel: 'formNamespace.label.create',
|
||||||
|
reuseLabel: 'formNamespace.label.reuse',
|
||||||
|
|
||||||
// Outputs
|
// Outputs
|
||||||
namespace: null,
|
namespace: null,
|
||||||
errors: null,
|
errors: null,
|
||||||
|
|
@ -25,6 +28,7 @@ export default Component.extend({
|
||||||
editing: true,
|
editing: true,
|
||||||
required: true,
|
required: true,
|
||||||
isReuse: equal('mode', REUSE),
|
isReuse: equal('mode', REUSE),
|
||||||
|
hookName: 'saveNamespace',
|
||||||
|
|
||||||
classNames: ['inline-form'],
|
classNames: ['inline-form'],
|
||||||
choices: alias('scope.currentProject.namespaces'),
|
choices: alias('scope.currentProject.namespaces'),
|
||||||
|
|
@ -64,7 +68,7 @@ export default Component.extend({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendAction('registerHook', this.saveNamespace.bind(this), {name: 'saveNamespace', key: '_beforeSaveHooks'});
|
this.sendAction('registerHook', this.saveNamespace.bind(this), {name: get(this,'hookName'), key: '_beforeSaveHooks'});
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,7 @@
|
||||||
{{#if editing}}
|
{{#if editing}}
|
||||||
<div class="clearfix">
|
<div class="clearfix">
|
||||||
<label class="acc-label pb-5">
|
<label class="acc-label pb-5">
|
||||||
{{#if isReuse}}
|
{{t (if isReuse reuseLabel createLabel)}}
|
||||||
{{t 'formNamespace.label.reuse'}}
|
|
||||||
{{else}}
|
|
||||||
{{t 'formNamespace.label.create'}}
|
|
||||||
{{/if}}
|
|
||||||
{{field-required}}
|
{{field-required}}
|
||||||
</label>
|
</label>
|
||||||
<div class="pull-right text-small">
|
<div class="pull-right text-small">
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,17 @@ export default Component.extend(ThrottledResize, {
|
||||||
accept: "text/*, .yml, .yaml",
|
accept: "text/*, .yml, .yaml",
|
||||||
multiple: false,
|
multiple: false,
|
||||||
viewportMargin: Infinity,
|
viewportMargin: Infinity,
|
||||||
maxHeight: 200,
|
autoResize: false,
|
||||||
|
resizeFooter: 130,
|
||||||
|
minHeight: 50,
|
||||||
inputName: false,
|
inputName: false,
|
||||||
canChangeName: true,
|
canChangeName: true,
|
||||||
canUpload: true,
|
canUpload: true,
|
||||||
showUploadLabel: true,
|
showUploadLabel: true,
|
||||||
gutters: ["CodeMirror-lint-markers"],
|
gutters: ["CodeMirror-lint-markers"],
|
||||||
tagName: ['div'],
|
tagName: ['div'],
|
||||||
|
showUpload: true,
|
||||||
|
showDownload: true,
|
||||||
|
|
||||||
_boundChange: null,
|
_boundChange: null,
|
||||||
shouldChangeName: true,
|
shouldChangeName: true,
|
||||||
|
|
@ -52,11 +56,13 @@ export default Component.extend(ThrottledResize, {
|
||||||
},
|
},
|
||||||
|
|
||||||
onResize() {
|
onResize() {
|
||||||
|
if ( get(this,'autoResize') ) {
|
||||||
this.fit();
|
this.fit();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
fit() {
|
fit() {
|
||||||
if ( get(this, 'maxHeight') === 'auto' ) {
|
if ( get(this, 'autoResize') ) {
|
||||||
var container = this.$('.codemirror-container');
|
var container = this.$('.codemirror-container');
|
||||||
if ( !container ) {
|
if ( !container ) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -67,8 +73,8 @@ export default Component.extend(ThrottledResize, {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const desired = $(window).height() - position.top - 130;
|
const desired = $(window).height() - position.top - get(this,'resizeFooter');
|
||||||
container.css('max-height', Math.max(400, desired));
|
container.css('max-height', Math.max(get(this,'minHeight'), desired));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
{{#if title}}
|
{{#if title}}
|
||||||
<section class="header clearfix">
|
<section class="header clearfix">
|
||||||
<div class="right-buttons">
|
<div class="right-buttons">
|
||||||
|
{{#if showUpload}}
|
||||||
<button class="btn bg-link icon-btn" {{action "click"}}>
|
<button class="btn bg-link icon-btn" {{action "click"}}>
|
||||||
<span class="darken"><i class="icon icon-upload text-small"/></span>
|
<span class="darken"><i class="icon icon-upload text-small"/></span>
|
||||||
<span>{{t 'inputTextFile.tooltip'}}</span>
|
<span>{{t 'inputTextFile.tooltip'}}</span>
|
||||||
</button>
|
</button>
|
||||||
|
{{/if}}
|
||||||
|
{{#if showDownload}}
|
||||||
<button class="btn bg-link icon-btn p-0" {{action "download"}}>
|
<button class="btn bg-link icon-btn p-0" {{action "download"}}>
|
||||||
<span class="darken"><i class="icon icon-download text-small"/></span>
|
<span class="darken"><i class="icon icon-download text-small"/></span>
|
||||||
<span>{{t 'generic.download'}}</span>
|
<span>{{t 'generic.download'}}</span>
|
||||||
</button>
|
</button>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<h1>{{title}}</h1>
|
<h1>{{title}}</h1>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
import Component from '@ember/component';
|
||||||
|
import { get, set, observer } from '@ember/object';
|
||||||
|
import { inject as service } from '@ember/service';
|
||||||
|
import CodeMirror from 'codemirror';
|
||||||
|
import jsyaml from 'npm:js-yaml';
|
||||||
|
import ModalBase from 'shared/mixins/modal-base';
|
||||||
|
import layout from './template';
|
||||||
|
import ChildHook from 'shared/mixins/child-hook';
|
||||||
|
|
||||||
|
export default Component.extend(ModalBase, ChildHook, {
|
||||||
|
layout,
|
||||||
|
intl: service(),
|
||||||
|
growl: service(),
|
||||||
|
scope: service(),
|
||||||
|
store: service('store'),
|
||||||
|
|
||||||
|
mode: 'project',
|
||||||
|
namespace: null,
|
||||||
|
yaml: '',
|
||||||
|
|
||||||
|
errors: null,
|
||||||
|
compose: null,
|
||||||
|
classNames: ['modal-container', 'large-modal', 'fullscreen-modal', 'modal-shell', 'alert'],
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this._super(...arguments);
|
||||||
|
window.jsyaml||(window.jsyaml=jsyaml);
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
cancel() {
|
||||||
|
return this._super(...arguments);
|
||||||
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
return this._super(...arguments);
|
||||||
|
},
|
||||||
|
|
||||||
|
save(cb) {
|
||||||
|
let yaml = get(this,'yaml');
|
||||||
|
let lintError = CodeMirror.lint.yaml(yaml);
|
||||||
|
|
||||||
|
if( lintError.length ) {
|
||||||
|
set(this,'errors', [get(this,'intl').t('yamlPage.errors')]);
|
||||||
|
cb(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set(this,'errors', null);
|
||||||
|
|
||||||
|
const opts = {
|
||||||
|
yaml: get(this, 'yaml'),
|
||||||
|
};
|
||||||
|
|
||||||
|
switch ( get(this, 'mode') ) {
|
||||||
|
case 'namespace':
|
||||||
|
opts.namespace = get(this, 'namespace.name');
|
||||||
|
break;
|
||||||
|
case 'project':
|
||||||
|
opts.project = get(this, 'projectId');
|
||||||
|
opts.defaultNamespace = get(this, 'namespace.name');
|
||||||
|
break;
|
||||||
|
case 'cluster':
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( get(this, 'mode') === 'cluster' ) {
|
||||||
|
this.send('actuallySave', opts, cb);
|
||||||
|
} else {
|
||||||
|
return this.applyHooks('_beforeSaveHooks').then(() => {
|
||||||
|
this.send('actuallySave', opts, cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actuallySave(opts, cb) {
|
||||||
|
return get(this, 'scope.currentCluster').doAction('importYaml', opts).then(() => {
|
||||||
|
cb();
|
||||||
|
this.send('cancel');
|
||||||
|
}).catch(() => {
|
||||||
|
cb(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
lintObserver: observer('yaml', function() {
|
||||||
|
const yaml = get(this,'yaml');
|
||||||
|
const lintError = CodeMirror.lint.yaml(yaml);
|
||||||
|
|
||||||
|
if ( lintError.length ) {
|
||||||
|
set(this,'errors', null);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
|
||||||
|
{{input-yaml
|
||||||
|
title=(t 'modalImport.title')
|
||||||
|
name="import.yaml"
|
||||||
|
canChangeName=false
|
||||||
|
value=yaml
|
||||||
|
autoResize=true
|
||||||
|
resizeFooter=250
|
||||||
|
showDownload=false
|
||||||
|
}}
|
||||||
|
|
||||||
|
<div class="mt-20 row">
|
||||||
|
<div class="col span-6">
|
||||||
|
<label class="acc-label">{{t 'modalImport.mode.label'}}</label>
|
||||||
|
<div>
|
||||||
|
<label>{{radio-button selection=mode value="cluster"}} {{t 'modalImport.mode.cluster'}}</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>{{radio-button selection=mode value="project"}} {{t 'modalImport.mode.project'}}</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>{{radio-button selection=mode value="namespace"}} {{t 'modalImport.mode.namespace'}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col span-6">
|
||||||
|
{{#unless (eq mode 'cluster')}}
|
||||||
|
{{form-namespace
|
||||||
|
reuseLabel=(if (eq mode 'project') 'formNamespace.label.default' 'formNamespace.label.reuse')
|
||||||
|
namespace=namespace
|
||||||
|
errors=namespaceErrors
|
||||||
|
registerHook=(action "registerHook")
|
||||||
|
}}
|
||||||
|
{{/unless}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{top-errors errors=errors}}
|
||||||
|
{{save-cancel save="save" cancel="cancel" editing=editing createLabel='generic.import'}}
|
||||||
|
|
@ -33,6 +33,7 @@ export default Component.extend(NodeDriver, {
|
||||||
diskSize: 20000,
|
diskSize: 20000,
|
||||||
vcenterPort: 443,
|
vcenterPort: 443,
|
||||||
network: [],
|
network: [],
|
||||||
|
boot2dockerUrl: 'https://github.com/boot2docker/boot2docker/releases/download/v17.03.2-ce/boot2docker.iso'
|
||||||
});
|
});
|
||||||
|
|
||||||
set(this, `model.${CONFIG}`, config);
|
set(this, `model.${CONFIG}`, config);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export { default } from 'shared/components/modal-import/component';
|
||||||
|
|
@ -46,6 +46,7 @@ generic:
|
||||||
help: Help
|
help: Help
|
||||||
id: ID
|
id: ID
|
||||||
image: Image
|
image: Image
|
||||||
|
import: Import
|
||||||
internal: Internal
|
internal: Internal
|
||||||
ipAddress: IP Address
|
ipAddress: IP Address
|
||||||
key: Key
|
key: Key
|
||||||
|
|
@ -3592,6 +3593,7 @@ formNamespace:
|
||||||
label:
|
label:
|
||||||
reuse: Namespace
|
reuse: Namespace
|
||||||
create: Namespace
|
create: Namespace
|
||||||
|
default: Default Namespace
|
||||||
toggle:
|
toggle:
|
||||||
simple: Customize
|
simple: Customize
|
||||||
reuse: Use an existing namespace
|
reuse: Use an existing namespace
|
||||||
|
|
@ -4151,6 +4153,17 @@ modalHostEvacuate:
|
||||||
protip: "ProTip: Hold the {key} key while clicking stop to bypass this confirmation."
|
protip: "ProTip: Hold the {key} key while clicking stop to bypass this confirmation."
|
||||||
button: Evacuate
|
button: Evacuate
|
||||||
|
|
||||||
|
modalImport:
|
||||||
|
title: Import YAML
|
||||||
|
mode:
|
||||||
|
label: Import Mode
|
||||||
|
cluster: "Cluster: Direct import of any resources into this cluster"
|
||||||
|
project: "Project: Import resources into this project"
|
||||||
|
namespace: "Namespace: Import resources into a specific namespace"
|
||||||
|
defaultNamespace:
|
||||||
|
label: Default namespace for resources that don't specify one
|
||||||
|
|
||||||
|
|
||||||
modalProcessError:
|
modalProcessError:
|
||||||
header: Exception Info
|
header: Exception Info
|
||||||
cause: "Cause:"
|
cause: "Cause:"
|
||||||
|
|
@ -4552,7 +4565,7 @@ nodeDriver:
|
||||||
access:
|
access:
|
||||||
title: 1. Account Access
|
title: 1. Account Access
|
||||||
detail: Configure where to find the VCenter or ESXi server
|
detail: Configure where to find the VCenter or ESXi server
|
||||||
help: "Note: The free ESXi liecense does not support API access. Only paid license servers are supported."
|
help: "Note: The free ESXi liecense does not support API access. Only servers with a valid or evaluation license are supported."
|
||||||
instance:
|
instance:
|
||||||
title: 2. Instance Options
|
title: 2. Instance Options
|
||||||
detail: Choose the size and OS of the virtual machine
|
detail: Choose the size and OS of the virtual machine
|
||||||
|
|
@ -4560,10 +4573,10 @@ nodeDriver:
|
||||||
title: 3. Scheduling
|
title: 3. Scheduling
|
||||||
detail: Choose what hypervisor the virtual machine will be scheduled to
|
detail: Choose what hypervisor the virtual machine will be scheduled to
|
||||||
vcenter:
|
vcenter:
|
||||||
label: vCenter Host
|
label: vCenter or ESXi Server
|
||||||
placeholder: vCenter or ESXi hostname/IP
|
placeholder: vCenter or ESXi hostname/IP
|
||||||
vcenterPort:
|
vcenterPort:
|
||||||
label: vCenter Port
|
label: Port
|
||||||
username:
|
username:
|
||||||
label: Username
|
label: Username
|
||||||
password:
|
password:
|
||||||
|
|
@ -4585,24 +4598,24 @@ nodeDriver:
|
||||||
schedulingSection: Scheduling
|
schedulingSection: Scheduling
|
||||||
dataCenter:
|
dataCenter:
|
||||||
label: Data Center
|
label: Data Center
|
||||||
placeholder: "datacenter_name"
|
placeholder: "e.g. datacenter_name"
|
||||||
help: "Datacenter for Docker VM (must be set to ha-datacenter when connecting to a single host)."
|
help: "Data Center to create VM in (leave blank for standalone ESXi)"
|
||||||
pool:
|
pool:
|
||||||
label: Pool
|
label: Pool
|
||||||
placeholder: "/dc_name/host/host_name/Resources/pool_name"
|
placeholder: "e.g. /dc_name/host/host_name/Resources/pool_name"
|
||||||
help: "Resource pool for Docker VM."
|
help: "Resource Pool to create VM in (leave blank for standalone ESXi)"
|
||||||
host:
|
host:
|
||||||
label: Host
|
label: Host
|
||||||
placeholder: "cluster_name/host_name"
|
placeholder: "e.g. cluster_name/host_name"
|
||||||
help: "vSphere compute resource where the docker VM is instantiated. This can be omitted if using a cluster with DRS."
|
help: "Specific host to create VM on (leave blank for standalon ESXi or for cluster with DRS)"
|
||||||
network:
|
network:
|
||||||
label: Network
|
label: Network
|
||||||
placeholder: "VM Traffic"
|
placeholder: "e.g. VM Network"
|
||||||
help: "Network where the Docker VM is attached."
|
help: "Network to attach VM to"
|
||||||
dataStore:
|
dataStore:
|
||||||
label: Data Store
|
label: Data Store
|
||||||
placeholder: "datastore_cluster_name/datastore_name"
|
placeholder: "e.g. datastore_cluster_name/datastore_name"
|
||||||
help: "Datastore for Docker VM."
|
help: "Datastore to create VM disk on"
|
||||||
azure:
|
azure:
|
||||||
placement:
|
placement:
|
||||||
title: Placement
|
title: Placement
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue