mirror of https://github.com/rancher/ui.git
commit
5c37ba9cfb
|
|
@ -65,6 +65,7 @@ module.exports = {
|
|||
"no-useless-escape": 0,
|
||||
"ember/use-ember-get-and-set": 0,
|
||||
"ember/order-in-controllers": 0,
|
||||
"ember/order-in-models": 0,
|
||||
"ember/closure-actions": 0,
|
||||
"ember/order-in-components": 0,
|
||||
"ember/no-on-calls-in-components": 0,
|
||||
|
|
|
|||
|
|
@ -2,24 +2,10 @@
|
|||
<h1 class="pull-left">{{t 'clustersPage.header'}}</h1> <div class="vertical-middle"></div>
|
||||
|
||||
<div class="right-buttons">
|
||||
<div class="btn-group p-0 mr-10">
|
||||
{{#tooltip-element type="tooltip-basic" model=(t 'clustersPage.mode.list') tooltipTemplate='tooltip-static' aria-describedby="tooltip-base" tooltipFor="tooltipLink"}}
|
||||
{{#link-to (query-params mode="list") classNames="btn btn-sm bg-default"}}<i class="icon icon-list"></i>{{/link-to}}
|
||||
{{/tooltip-element}}
|
||||
{{#tooltip-element type="tooltip-basic" model=(t 'clustersPage.mode.grouped') tooltipTemplate='tooltip-static' aria-describedby="tooltip-base" tooltipFor="tooltipLink"}}
|
||||
{{#link-to (query-params mode="grouped") classNames="btn btn-sm bg-default"}}<i class="icon icon-boxview"></i>{{/link-to}}
|
||||
{{/tooltip-element}}
|
||||
</div>
|
||||
|
||||
{{#link-to "authenticated.clusters.new" class="btn bg-primary btn-sm icon-btn"}}
|
||||
<span class="darken"><i class="icon icon-cluster"></i></span>
|
||||
<span>{{t 'clustersPage.newCluster'}}</span>
|
||||
{{/link-to}}
|
||||
|
||||
{{#link-to "authenticated.clusters.new-project" class="btn bg-primary btn-sm icon-btn" disabled=(eq model.clusters.length 0)}}
|
||||
<span class="darken"><i class="icon icon-folder"></i></span>
|
||||
<span>{{t 'clustersPage.newProject'}}</span>
|
||||
{{/link-to}}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -32,36 +18,29 @@
|
|||
</section>
|
||||
{{/unless}}
|
||||
|
||||
{{#if (eq mode "grouped")}}
|
||||
{{#sortable-table
|
||||
classNames="grid sortable-table"
|
||||
body=model.clusters
|
||||
searchText=searchText
|
||||
sortBy=sortBy
|
||||
bulkActions=false
|
||||
fullRows=true
|
||||
subRows=true
|
||||
pagingLabel="pagination.cluster"
|
||||
headers=headers as |sortable kind inst dt|
|
||||
}}
|
||||
{{#if (eq kind "row")}}
|
||||
{{cluster-row
|
||||
model=inst
|
||||
fullColspan=sortable.fullColspan
|
||||
toggle=(action "toggleExpand" inst.id)
|
||||
expanded=(array-includes expandedClusters inst.id)
|
||||
launchOnCluster=(action "launchOnCluster")
|
||||
useKubernetes=(action "useKubernetes")
|
||||
dt=dt
|
||||
}}
|
||||
{{else if (eq kind "nomatch")}}
|
||||
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'clusterRow.noClusterMatch'}}</td></tr>
|
||||
{{else if (eq kind "norows")}}
|
||||
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'clusterRow.noClusterData'}}</td></tr>
|
||||
{{/if}}
|
||||
{{/sortable-table}}
|
||||
{{else}}
|
||||
{{project-table model=model.projects showCluster=true}}
|
||||
{{/if}}
|
||||
|
||||
<div class="mt-30 box">{{t 'clustersPage.subtext' appName=settings.appName htmlSafe=true}}</div>
|
||||
{{#sortable-table
|
||||
classNames="grid sortable-table"
|
||||
body=model.clusters
|
||||
searchText=searchText
|
||||
sortBy=sortBy
|
||||
bulkActions=false
|
||||
fullRows=true
|
||||
pagingLabel="pagination.cluster"
|
||||
headers=headers as |sortable kind inst dt|
|
||||
}}
|
||||
{{#if (eq kind "row")}}
|
||||
{{cluster-row
|
||||
model=inst
|
||||
fullColspan=sortable.fullColspan
|
||||
toggle=(action "toggleExpand" inst.id)
|
||||
expanded=(array-includes expandedClusters inst.id)
|
||||
launchOnCluster=(action "launchOnCluster")
|
||||
useKubernetes=(action "useKubernetes")
|
||||
dt=dt
|
||||
}}
|
||||
{{else if (eq kind "nomatch")}}
|
||||
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'clusterRow.noClusterMatch'}}</td></tr>
|
||||
{{else if (eq kind "norows")}}
|
||||
<tr><td colspan="{{sortable.fullColspan}}" class="text-center text-muted lacsso pt-20 pb-20">{{t 'clusterRow.noClusterData'}}</td></tr>
|
||||
{{/if}}
|
||||
{{/sortable-table}}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
import EmberObject from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Route from '@ember/routing/route';
|
||||
import C from 'ui/utils/constants';
|
||||
|
||||
export default Route.extend({
|
||||
clusterStore: service('cluster-store'),
|
||||
catalog: service(),
|
||||
settings: service(),
|
||||
|
||||
model() {
|
||||
// TODO - !!FORDEV!! removed for dev sake
|
||||
let store = this.get('clusterStore');
|
||||
let def = JSON.parse(this.get(`settings.${C.SETTING.CLUSTER_TEMPLATE}`)) || {};
|
||||
|
||||
def.type = 'cluster';
|
||||
// def.systemStacks = (def.systemStacks||[]).map((stack) => {
|
||||
// stack.type = 'stackConfiguration';
|
||||
// return stack;
|
||||
// });
|
||||
|
||||
let cluster = store.createRecord(def);
|
||||
|
||||
// return this.get('catalog').fetchTemplates({plusInfra: true}).then((templates) => {
|
||||
// return EmberObject.create({
|
||||
// cluster: cluster,
|
||||
// allTemplates: templates
|
||||
// });
|
||||
// });
|
||||
return EmberObject.create({cluster: cluster, allTemplates: []});
|
||||
},
|
||||
// teardownForComponentState: on('deactivate', function(){
|
||||
// this.controller.setProperties({
|
||||
// catalogItem: null,
|
||||
// editCatalog: false,
|
||||
// selectedTemplateUrl: null,
|
||||
// catalogInfo: null,
|
||||
// _catalogInfoCache: null,
|
||||
// _prefetchInstance: null,
|
||||
// catalogId: 'all',
|
||||
// category: null,
|
||||
// viewCatalog: false,
|
||||
// newSystemStack: null,
|
||||
// });
|
||||
// })
|
||||
});
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<section class="header">
|
||||
<h1>{{t 'clustersPage.newCluster'}}</h1>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="row">
|
||||
<div class="col span-4 text-center option option-primary">
|
||||
<h2>{{t 'clustersPage.indexPage.rke.header'}}</h2>
|
||||
<div class="box-sm">
|
||||
<p>{{t 'clustersPage.indexPage.rke.desc'}}</p>
|
||||
<div class="links" style="top: auto; bottom: 30px;">
|
||||
{{#link-to "authenticated.clusters.new.rke" class="btn bg-primary"}}{{t 'clusterWelcome.select'}}{{/link-to}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="bubble bg-body round p-10"><img src="{{app.baseAssets}}assets/images/environment-standard.svg" class="mt-5" /></div>
|
||||
</div>
|
||||
<div class="col span-4 text-center option option-disabled">
|
||||
<h2>{{t 'clustersPage.indexPage.cloud.header'}}</h2>
|
||||
<div class="box-sm">
|
||||
<p>{{t 'clustersPage.indexPage.cloud.desc'}}</p>
|
||||
<div class="links" style="top: auto; bottom: 30px;">
|
||||
{{#link-to "authenticated.clusters.cluster.host-templates" scope.currentCluster.id class="btn bg-primary"}}{{t 'clusterWelcome.select'}}{{/link-to}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="bubble bg-body round p-10"><img src="{{app.baseAssets}}assets/images/cluster-key.svg" class="mt-5" /></div>
|
||||
</div>
|
||||
<div class="col span-4 text-center option option-disabled">
|
||||
<h2>{{t 'clustersPage.indexPage.import.header'}}</h2>
|
||||
<div class="box-sm">
|
||||
<p>{{t 'clustersPage.indexPage.import.desc'}}</p>
|
||||
<div class="links" style="top: auto; bottom: 30px;">
|
||||
{{#link-to "authenticated.clusters.cluster.host-templates" scope.currentCluster.id class="btn bg-primary"}}{{t 'clusterWelcome.select'}}{{/link-to}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="bubble bg-body round p-10"><img src="{{app.baseAssets}}assets/images/environment-import.svg" class="mt-5" /></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
import Controller from '@ember/controller';
|
||||
// import { copy } from '@ember/object/internals';
|
||||
import { get, set } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { computed,observer } from '@ember/object';
|
||||
import { alias } from '@ember/object/computed';
|
||||
|
||||
const CONFIG_DEFAULT = {
|
||||
advertisedHostname: '',
|
||||
role: null,
|
||||
type: 'rkeConfigHost',
|
||||
user: '',
|
||||
ssh: '',
|
||||
};
|
||||
|
||||
export default Controller.extend({
|
||||
modalService: service('modal'),
|
||||
store: service('cluster-store'),
|
||||
step: null,
|
||||
loading: null,
|
||||
newHost: null,
|
||||
// clusterList: null,
|
||||
canAdd: null,
|
||||
cluster: alias('model'),
|
||||
config: alias('model.rancherKubernetesEngineConfig'),
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
let newHostConfig = get(this, 'store').createRecord(CONFIG_DEFAULT);
|
||||
set(newHostConfig, 'role', ['etcd']);
|
||||
this.setProperties({
|
||||
step: 1,
|
||||
newHost: newHostConfig,
|
||||
loading: false,
|
||||
canAdd: false,
|
||||
});
|
||||
},
|
||||
|
||||
workerList: computed('config.hosts.@each.{role,advertisedHostname,user}', function() {
|
||||
return ( get(this, 'config.hosts') || [] ).filter((host) => {
|
||||
return (get(host, 'role')||[]).includes('worker');
|
||||
});
|
||||
}),
|
||||
|
||||
controlplaneList: computed('config.hosts.@each.{role,advertisedHostname,user}', function() {
|
||||
return ( get(this, 'config.hosts') || [] ).filter((host) => {
|
||||
return (get(host, 'role')||[]).includes('controlplane');
|
||||
});
|
||||
}),
|
||||
|
||||
clusterList: computed('config.hosts.@each.{role,advertisedHostname,user,ssh}', function() {
|
||||
// unfilterd list of host
|
||||
return ( get(this, 'config.hosts') || [] ).uniq();
|
||||
}),
|
||||
|
||||
hostObserver: observer('newHost.user','newHost.advertisedHostname','newHost.ssh', function() {
|
||||
let cName = get(this, 'newHost.user');
|
||||
let hName = get(this, 'newHost.advertisedHostname');
|
||||
let ssh = get(this, 'newHost.ssh');
|
||||
(cName.length > 0) && (hName.length > 0) && (ssh.length > 0) ? set(this, 'canAdd', true) : set(this, 'canAdd', false);
|
||||
}),
|
||||
|
||||
actions: {
|
||||
save() {
|
||||
},
|
||||
cancel(prev) {
|
||||
this.send('goToPrevious',prev);
|
||||
},
|
||||
addNew(type) {
|
||||
// TODO - set role
|
||||
let neu = CONFIG_DEFAULT;
|
||||
set(neu, 'role', []);
|
||||
this.get('modalService').toggleModal('modal-add-cluster', {
|
||||
newHost: get(this, 'store').createRecord(neu),
|
||||
list: get(this, type),
|
||||
});
|
||||
},
|
||||
go() {
|
||||
this.incrementProperty('step');
|
||||
},
|
||||
back() {
|
||||
this.decrementProperty('step');
|
||||
},
|
||||
addHost() {
|
||||
get(this, 'config.hosts').pushObject(get(this, 'newHost'));
|
||||
set(this, 'newHost', get(this, 'store').createRecord(CONFIG_DEFAULT));
|
||||
},
|
||||
removeHost(host, roleToRemove) {
|
||||
let roles = get(host, 'role');
|
||||
let at = roles.indexOf(roleToRemove);
|
||||
if (at >= 0) {
|
||||
roles.removeAt(at);
|
||||
if (roles.length === 0) {
|
||||
get(this, 'config.hosts').removeObject(host);
|
||||
}
|
||||
}
|
||||
},
|
||||
useFor(host, role) {
|
||||
// set knows nothing changed so it will not fire the computed propertiy change events
|
||||
let roles = get(host, 'role').slice(); //clone the array
|
||||
roles.addObject(role);
|
||||
set(host, 'role', roles);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import Ember from 'ember';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { get, set } from '@ember/object';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
store: service('cluster-store'),
|
||||
model: function(/* params, transition */) {
|
||||
// TODO - !!FORDEV!! get clusters
|
||||
let store = get(this, 'store');
|
||||
let def = {
|
||||
type: 'rancherKubernetesEngineConfig',
|
||||
hosts: [],
|
||||
network: 'flannel',
|
||||
auth: 'x509'
|
||||
};
|
||||
let config = store.createRecord(def);
|
||||
let cluster = this.modelFor('authenticated.clusters.new.index');
|
||||
set(cluster, 'rancherKubernetesEngineConfig', config);
|
||||
return cluster;
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
<section class="header">
|
||||
{{t 'clustersPage.addPage.rke.header' count=step}}
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="row">
|
||||
{{#if (eq step 1)}}
|
||||
<form class="form text-left">
|
||||
{{partial "add-cluster"}}
|
||||
<div class="row mb-20">
|
||||
<button {{action 'addHost'}} class="btn bg-primary mt-10 pull-right {{not canAdd 'disabled'}}" disabled={{not canAdd}}>{{t 'generic.add'}}</button>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row mt-10">
|
||||
{{#each config.hosts as | cluster |}}
|
||||
<div class="row help-text mt-10 mb-10">{{t 'clustersPage.addPage.rke.minimums.cluster'}}</div>
|
||||
<div class="col span-12 border">
|
||||
<div class="col span-10 pl-5 ">
|
||||
<h2 class="mt-5 mb-0">{{cluster.advertisedHostname}}</h2>
|
||||
</div>
|
||||
<div class="col span-2 text-right">
|
||||
<button class="btn btn-sm bg-transparent" {{action 'removeHost' cluster 'etcd'}}><i class="icon icon-close mr-5"></i> {{t 'generic.remove'}}</button>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="mt-10 mb-10">
|
||||
<div class="row help-text">{{t 'clustersPage.addPage.rke.minimums.nocluster'}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="text-center pt-10">
|
||||
{{#if loading}}
|
||||
<button class="btn bg-primary btn-disabled" disabled><i class="icon icon-spinner icon-spin"></i> {{t 'generic.loading'}}</button>
|
||||
{{else}}
|
||||
{{#if config.hosts.length }}
|
||||
<button {{action 'go'}} class="btn bg-primary {{not clusterList.length 'disabled'}}" disbaled={{not clusterList.length}}>{{t 'generic.save'}}</button>
|
||||
{{else}}
|
||||
<button class="btn bg-primary disabled" disabled>{{t 'generic.save'}}</button>
|
||||
{{/if}}
|
||||
<button {{action "cancel"}} class="btn bg-primary">{{t 'generic.cancel'}}</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
</form>
|
||||
{{else if (eq step 2) }}
|
||||
<form class="form text-left">
|
||||
<div class="row">
|
||||
{{#each controlplaneList as | cluster |}}
|
||||
<div class="row help-text mt-10 mb-10">{{t 'clustersPage.addPage.rke.minimums.management'}}</div>
|
||||
<div class="col span-12 border">
|
||||
<div class="col span-10 pl-5 ">
|
||||
<h2 class="mt-5 mb-0">{{cluster.advertisedHostname}}</h2>
|
||||
</div>
|
||||
<div class="col span-2 text-right">
|
||||
<button class="btn btn-sm bg-transparent" {{action 'removeHost' cluster 'controlplane'}}><i class="icon icon-close mr-5"></i> {{t 'generic.remove'}}</button>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="row help-text">{{t 'clustersPage.addPage.rke.minimums.noManagement'}}</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
{{#if clusterList.length }}
|
||||
<div class="row help-text mt-10 mb-10">{{t 'clustersPage.addPage.rke.reuse.nodes'}}</div>
|
||||
{{#each clusterList as | cluster |}}
|
||||
<div class="col span-12 border">
|
||||
<div class="col span-10 pl-5 ">
|
||||
<h2 class="mt-5 mb-0">{{cluster.advertisedHostname}}</h2>
|
||||
</div>
|
||||
<div class="col span-2 text-right">
|
||||
<button class="btn btn-sm bg-transparent" {{action 'useFor' cluster 'controlplane'}}>{{t 'clustersPage.addPage.rke.reuse.management'}}</button>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="text-center">
|
||||
{{#if loading}}
|
||||
<button class="btn bg-primary mt-10 btn-disabled" disabled><i class="icon icon-spinner icon-spin"></i> {{t 'generic.loading'}}</button>
|
||||
{{else}}
|
||||
<button {{action 'addNew' 'controlplaneList'}} class="btn bg-primary mt-10" >{{t 'generic.add'}}</button>
|
||||
{{#if controlplaneList.length }}
|
||||
<button {{action 'go'}} class="btn bg-primary mt-10" >{{t 'generic.save'}}</button>
|
||||
{{else}}
|
||||
<button class="btn bg-primary mt-10 disabled" disabled>{{t 'generic.save'}}</button>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</form>
|
||||
{{else if (eq step 3) }}
|
||||
<form class="form text-left">
|
||||
<div class="row">
|
||||
<div class="row help-text mt-10 mb-10">{{t 'clustersPage.addPage.rke.minimums.nodes'}}</div>
|
||||
{{#each workerList as | cluster |}}
|
||||
<div class="col span-12 border">
|
||||
<div class="col span-10 pl-5 ">
|
||||
<h2 class="mt-5 mb-0">{{cluster.advertisedHostname}}</h2>
|
||||
</div>
|
||||
<div class="col span-2 text-right">
|
||||
<button class="btn btn-sm bg-transparent" {{action 'removeHost' cluster 'worker'}}> <i class="icon icon-close mr-5"></i>{{t 'generic.remove'}}</button>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="mt-10 mb-10">
|
||||
<div class="row help-text mt-10 mb-10">{{t 'clustersPage.addPage.rke.minimums.noNodes'}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
{{#if clusterList.length }}
|
||||
<div class="row help-text mt-10 mb-10">{{t 'clustersPage.addPage.rke.reuse.nodes'}}</div>
|
||||
{{#each clusterList as | cluster |}}
|
||||
<div class="col span-12 border">
|
||||
<div class="col span-10 pl-5 ">
|
||||
<h2 class="mt-5 mb-0">{{cluster.advertisedHostname}}</h2>
|
||||
</div>
|
||||
<div class="col span-2 text-right">
|
||||
<button class="btn btn-sm bg-transparent" {{action 'useFor' cluster 'worker'}}> <i class="icon icon-close mr-5"></i>{{t 'clustersPage.addPage.rke.reuse.useNode'}}</button>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="text-center">
|
||||
{{#if loading}}
|
||||
<button class="btn bg-primary mt-10 btn-disabled" disabled><i class="icon icon-spinner icon-spin"></i> {{t 'generic.loading'}}</button>
|
||||
{{else}}
|
||||
<button {{action 'addNew' 'workerList'}} class="btn bg-primary mt-10" >{{t 'generic.add'}}</button>
|
||||
<button {{action 'save'}} class="btn bg-primary mt-10" >{{t 'generic.save'}}</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
</form>
|
||||
{{/if}}
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
import { on } from '@ember/object/evented';
|
||||
import EmberObject from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Route from '@ember/routing/route';
|
||||
import C from 'ui/utils/constants';
|
||||
|
||||
export default Route.extend({
|
||||
clusterStore: service('cluster-store'),
|
||||
catalog: service(),
|
||||
settings: service(),
|
||||
|
||||
model() {
|
||||
let store = this.get('clusterStore');
|
||||
let def = JSON.parse(this.get(`settings.${C.SETTING.CLUSTER_TEMPLATE}`)) || {};
|
||||
|
||||
def.type = 'cluster';
|
||||
def.systemStacks = (def.systemStacks||[]).map((stack) => {
|
||||
stack.type = 'stackConfiguration';
|
||||
return stack;
|
||||
})
|
||||
|
||||
let cluster = store.createRecord(def);
|
||||
|
||||
return this.get('catalog').fetchTemplates({plusInfra: true}).then((templates) => {
|
||||
return EmberObject.create({
|
||||
cluster: cluster,
|
||||
allTemplates: templates
|
||||
});
|
||||
});
|
||||
},
|
||||
teardownForComponentState: on('deactivate', function(){
|
||||
this.controller.setProperties({
|
||||
catalogItem: null,
|
||||
editCatalog: false,
|
||||
selectedTemplateUrl: null,
|
||||
catalogInfo: null,
|
||||
_catalogInfoCache: null,
|
||||
_prefetchInstance: null,
|
||||
catalogId: 'all',
|
||||
category: null,
|
||||
viewCatalog: false,
|
||||
newSystemStack: null,
|
||||
});
|
||||
})
|
||||
});
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{{new-edit-cluster
|
||||
cancel=(action 'cancel')
|
||||
model=model
|
||||
editing=false
|
||||
}}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { hash } from 'rsvp';
|
||||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
|
|
@ -11,11 +10,12 @@ export default Route.extend({
|
|||
},
|
||||
|
||||
model() {
|
||||
const scope = this.get('scope');
|
||||
|
||||
return hash({
|
||||
projects: scope.getAll({all: true, removeMissing: true}),
|
||||
clusters: scope.getAllClusters({removeMissing: true}),
|
||||
var clusterStore = this.get('clusterStore');
|
||||
return clusterStore.find('cluster', null, {url: 'clusters', forceReload: true, removeMissing: true}).then(() => {
|
||||
//return a live array so its updated
|
||||
return {
|
||||
clusters: clusterStore.all('cluster'),
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -99,7 +99,8 @@ export default Route.extend(Subscribe, {
|
|||
if ( this.get('access.admin') && (!opt || opt === 'prompt') )
|
||||
{
|
||||
scheduleOnce('afterRender', this, function() {
|
||||
this.get('modalService').toggleModal('modal-telemetry');
|
||||
// TODO - !!FORDEV!! removed for dev sake
|
||||
// this.get('modalService').toggleModal('modal-telemetry');
|
||||
});
|
||||
}
|
||||
else if ( form && !this.get(`prefs.${C.PREFS.FEEDBACK}`) )
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
import Resource from 'ember-api-store/models/resource';
|
||||
import PolledResource from 'ui/mixins/cattle-polled-resource';
|
||||
|
||||
var AzureKubernetesServiceConfig = Resource.extend(PolledResource, {
|
||||
type: 'azureKubernetesServiceConfig',
|
||||
|
||||
reservedKeys: [],
|
||||
|
||||
actions: {
|
||||
deactivate() {
|
||||
return this.doAction('deactivate');
|
||||
},
|
||||
|
||||
activate() {
|
||||
return this.doAction('activate');
|
||||
},
|
||||
|
||||
edit: function() {
|
||||
},
|
||||
},
|
||||
|
||||
availableActions: function() {
|
||||
let a = this.get('actionLinks');
|
||||
let l = this.get('links');
|
||||
|
||||
return [
|
||||
{ label: 'action.edit', icon: 'icon icon-edit', action: 'edit', enabled: !!l.update },
|
||||
{ divider: true },
|
||||
{ label: 'action.activate', icon: 'icon icon-play', action: 'activate', enabled: !!a.activate , bulkable: true},
|
||||
{ label: 'action.deactivate', icon: 'icon icon-pause', action: 'deactivate', enabled: !!a.deactivate , bulkable: true},
|
||||
{ divider: true },
|
||||
{ label: 'action.remove', icon: 'icon icon-trash', action: 'promptDelete', enabled: !!l.remove, altAction: 'delete', bulkable: true },
|
||||
{ divider: true },
|
||||
{ label: 'action.viewInApi', icon: 'icon icon-external-link',action: 'goToApi', enabled: true },
|
||||
];
|
||||
}.property('actionLinks.{activate,deactivate,restore}','links.{update,remove}'),
|
||||
|
||||
});
|
||||
|
||||
export default AzureKubernetesServiceConfig;
|
||||
|
|
@ -40,7 +40,7 @@ var Cluster = Resource.extend(PolledResource, {
|
|||
|
||||
_allProjects: null,
|
||||
|
||||
projects: function() {
|
||||
projects: computed('_allProjects.@each.clusterName', function() {
|
||||
let x = this.get('_allProjects');
|
||||
|
||||
if (!x) {
|
||||
|
|
@ -48,9 +48,9 @@ var Cluster = Resource.extend(PolledResource, {
|
|||
}
|
||||
|
||||
return x.filterBy('clusterName', this.get('id'));
|
||||
}.property('_allProjects.@each.clusterName'),
|
||||
}),
|
||||
|
||||
defaultProject: function() {
|
||||
defaultProject: computed('projects.@each.{name,clusterOwner}', function() {
|
||||
let projects = this.get('projects');
|
||||
|
||||
let out = projects.findBy('name','Default');
|
||||
|
|
@ -64,54 +64,54 @@ var Cluster = Resource.extend(PolledResource, {
|
|||
}
|
||||
|
||||
return out;
|
||||
}.property('projects.@each.{name,clusterOwner}'),
|
||||
}),
|
||||
|
||||
canEdit: computed('actionLinks.{activate,deactivate}','links.{update,remove}', function() {
|
||||
return (this.get('links.update') && this.get('state') === 'inactive') ? true : false;
|
||||
}),
|
||||
|
||||
systemProject: function() {
|
||||
systemProject: computed('projects.@each.{clusterOwner}', function() {
|
||||
return this.get('projects').findBy('clusterOwner', true);
|
||||
}.property('projects.@each.{clusterOwner}'),
|
||||
}),
|
||||
|
||||
availableActions: function() {
|
||||
// let a = this.get('actionLinks');
|
||||
availableActions: computed('actionLinks.{activate,deactivate}','links.{update,remove}', function() {
|
||||
// let a = this.get('actionLinks');
|
||||
let l = this.get('links');
|
||||
|
||||
var choices = [
|
||||
{ label: 'action.edit', icon: 'icon icon-edit', action: 'edit', enabled: this.get('canEdit') },
|
||||
{ divider: true },
|
||||
// { label: 'action.activate', icon: 'icon icon-play', action: 'activate', enabled: !!a.activate},
|
||||
// { label: 'action.deactivate', icon: 'icon icon-pause', action: 'promptStop', enabled: !!a.deactivate, altAction: 'deactivate'},
|
||||
// { divider: true },
|
||||
// { label: 'action.activate', icon: 'icon icon-play', action: 'activate', enabled: !!a.activate},
|
||||
// { label: 'action.deactivate', icon: 'icon icon-pause', action: 'promptStop', enabled: !!a.deactivate, altAction: 'deactivate'},
|
||||
// { divider: true },
|
||||
{ label: 'action.remove', icon: 'icon icon-trash', action: 'promptDelete', enabled: !!l.remove, altAction: 'delete' },
|
||||
{ divider: true },
|
||||
{ label: 'action.viewInApi', icon: 'icon icon-external-link',action: 'goToApi', enabled: true },
|
||||
];
|
||||
|
||||
return choices;
|
||||
}.property('actionLinks.{activate,deactivate}','links.{update,remove}'),
|
||||
}),
|
||||
|
||||
// @TODO real data
|
||||
numHosts: function() {
|
||||
numHosts: computed(function() {
|
||||
return 3+Math.round(Math.random()*2);
|
||||
}.property(),
|
||||
}),
|
||||
|
||||
numCores: function() {
|
||||
numCores: computed('numHosts', function() {
|
||||
return this.get('numHosts')*8;
|
||||
}.property('numHosts'),
|
||||
}),
|
||||
|
||||
numGhz: function() {
|
||||
numGhz: computed('numCores', function() {
|
||||
return 3.4*this.get('numCores');
|
||||
}.property('numCores'),
|
||||
}),
|
||||
|
||||
numMem: function() {
|
||||
numMem: computed('numHosts', function() {
|
||||
return 8*this.get('numHosts');
|
||||
}.property('numHosts'),
|
||||
}),
|
||||
|
||||
numStorage: function() {
|
||||
numStorage: computed('numHosts', function() {
|
||||
return 40*this.get('numHosts');
|
||||
}.property('numHosts'),
|
||||
}),
|
||||
});
|
||||
|
||||
Cluster.reopenClass({
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
import Resource from 'ember-api-store/models/resource';
|
||||
import PolledResource from 'ui/mixins/cattle-polled-resource';
|
||||
|
||||
var GoogleKubernetesEngineConfig = Resource.extend(PolledResource, {
|
||||
type: 'googleKubernetesEngineConfig',
|
||||
|
||||
reservedKeys: [],
|
||||
|
||||
actions: {
|
||||
deactivate() {
|
||||
return this.doAction('deactivate');
|
||||
},
|
||||
|
||||
activate() {
|
||||
return this.doAction('activate');
|
||||
},
|
||||
|
||||
edit: function() {
|
||||
},
|
||||
},
|
||||
|
||||
availableActions: function() {
|
||||
let a = this.get('actionLinks');
|
||||
let l = this.get('links');
|
||||
|
||||
return [
|
||||
{ label: 'action.edit', icon: 'icon icon-edit', action: 'edit', enabled: !!l.update },
|
||||
{ divider: true },
|
||||
{ label: 'action.activate', icon: 'icon icon-play', action: 'activate', enabled: !!a.activate , bulkable: true},
|
||||
{ label: 'action.deactivate', icon: 'icon icon-pause', action: 'deactivate', enabled: !!a.deactivate , bulkable: true},
|
||||
{ divider: true },
|
||||
{ label: 'action.remove', icon: 'icon icon-trash', action: 'promptDelete', enabled: !!l.remove, altAction: 'delete', bulkable: true },
|
||||
{ divider: true },
|
||||
{ label: 'action.viewInApi', icon: 'icon icon-external-link',action: 'goToApi', enabled: true },
|
||||
];
|
||||
}.property('actionLinks.{activate,deactivate,restore}','links.{update,remove}'),
|
||||
|
||||
});
|
||||
|
||||
export default GoogleKubernetesEngineConfig;
|
||||
|
|
@ -130,7 +130,7 @@ var Stack = Resource.extend(StateCounts, {
|
|||
},
|
||||
},
|
||||
|
||||
availableActions: function() {
|
||||
availableActions: computed('actionLinks.{exportconfig}','links.{update,remove}','externalIdInfo.kind','canStartAll','canPauseAll','canStopAll', function() {
|
||||
let a = this.get('actionLinks');
|
||||
let l = this.get('links');
|
||||
|
||||
|
|
@ -156,9 +156,9 @@ var Stack = Resource.extend(StateCounts, {
|
|||
];
|
||||
|
||||
return out;
|
||||
}.property('actionLinks.{exportconfig}','links.{update,remove}','externalIdInfo.kind','canStartAll','canPauseAll','canStopAll'),
|
||||
}),
|
||||
|
||||
canStartAll: function() {
|
||||
canStartAll: computed('services.@each.state','actionLinks.startall', function() {
|
||||
if ( !this.hasAction('startall') ) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -169,9 +169,9 @@ var Stack = Resource.extend(StateCounts, {
|
|||
}
|
||||
|
||||
return this.get('services').filterBy('actionLinks.activate').get('length') > 0;
|
||||
}.property('services.@each.state','actionLinks.startall'),
|
||||
}),
|
||||
|
||||
canPauseAll: function() {
|
||||
canPauseAll: computed('services.@each.state','actionLinks.pauseall', function() {
|
||||
if ( !this.hasAction('pauseall') ) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -182,9 +182,9 @@ var Stack = Resource.extend(StateCounts, {
|
|||
}
|
||||
|
||||
return this.get('services').filterBy('actionLinks.pause').get('length') > 0;
|
||||
}.property('services.@each.state','actionLinks.pauseall'),
|
||||
}),
|
||||
|
||||
canStopAll: function() {
|
||||
canStopAll: computed('services.@each.state','actionLinks.stopall', function() {
|
||||
if ( !this.hasAction('stopall') ) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -201,13 +201,13 @@ var Stack = Resource.extend(StateCounts, {
|
|||
}
|
||||
|
||||
return services.filterBy('actionLinks.deactivate').get('length') > 0 && containers.filterBy('actionLinks.stop').get('length');
|
||||
}.property('services.@each.state','actionLinks.stopall'),
|
||||
}),
|
||||
|
||||
canViewConfig: function() {
|
||||
canViewConfig: computed('actionLinks.exportconfig', function() {
|
||||
return !!this.get('actionLinks.exportconfig');
|
||||
}.property('actionLinks.exportconfig'),
|
||||
}),
|
||||
|
||||
combinedState: function() {
|
||||
combinedState: computed('state', 'healthState', function() {
|
||||
var stack = this.get('state');
|
||||
var health = this.get('healthState');
|
||||
|
||||
|
|
@ -216,15 +216,15 @@ var Stack = Resource.extend(StateCounts, {
|
|||
} else {
|
||||
return stack;
|
||||
}
|
||||
}.property('state', 'healthState'),
|
||||
}),
|
||||
|
||||
externalIdInfo: function() {
|
||||
externalIdInfo: computed('externalId', function() {
|
||||
return parseExternalId(this.get('externalId'));
|
||||
}.property('externalId'),
|
||||
}),
|
||||
|
||||
isDefault: function() {
|
||||
isDefault: computed('name', function() {
|
||||
return (this.get('name')||'').toLowerCase() === 'default';
|
||||
}.property('name'),
|
||||
}),
|
||||
|
||||
isEmpty: computed('instances.length', 'services.length', function() {
|
||||
return false; // @TODO-2.0
|
||||
|
|
@ -236,25 +236,57 @@ var Stack = Resource.extend(StateCounts, {
|
|||
return false;
|
||||
}),
|
||||
|
||||
isFromCatalog: function() {
|
||||
isFromCatalog: computed('externalIdInfo.kind', function() {
|
||||
let kind = this.get('externalIdInfo.kind');
|
||||
return kind === C.EXTERNAL_ID.KIND_CATALOG || kind === C.EXTERNAL_ID.KIND_SYSTEM_CATALOG;
|
||||
}.property('externalIdInfo.kind'),
|
||||
}),
|
||||
|
||||
// This only works if the templates have already been loaded elsewhere...
|
||||
catalogTemplate: function() {
|
||||
catalogTemplate: computed('externalIdInfo.templateId', function() {
|
||||
return this.get('catalog').getTemplateFromCache(this.get('externalIdInfo.templateId'));
|
||||
}.property('externalIdInfo.templateId'),
|
||||
}),
|
||||
|
||||
icon: function() {
|
||||
icon: computed('catalogTemplate', function() {
|
||||
let tpl = this.get('catalogTemplate');
|
||||
if ( tpl ) {
|
||||
return tpl.linkFor('icon');
|
||||
}
|
||||
}.property('catalogTemplate'),
|
||||
}),
|
||||
|
||||
normalizedTags: computed('tags.[]', function() {
|
||||
return normalizedTags(this.get('tags'));
|
||||
grouping: computed('externalIdInfo.kind','group','system', function() {
|
||||
var kind = this.get('externalIdInfo.kind');
|
||||
|
||||
if ( kind === C.EXTERNAL_ID.KIND_KUBERNETES || kind === C.EXTERNAL_ID.KIND_LEGACY_KUBERNETES )
|
||||
{
|
||||
return C.EXTERNAL_ID.KIND_KUBERNETES;
|
||||
}
|
||||
else if ( this.get('system') )
|
||||
{
|
||||
return C.EXTERNAL_ID.KIND_INFRA;
|
||||
}
|
||||
else
|
||||
{
|
||||
return C.EXTERNAL_ID.KIND_USER;
|
||||
}
|
||||
}),
|
||||
|
||||
normalizedTags: computed('group', {
|
||||
get() {
|
||||
return tagsToArray(this.get('group'));
|
||||
},
|
||||
set(key,value) {
|
||||
this.set('group', (value||[]).map((x) => normalizeTag(x)).join(', '));
|
||||
return value;
|
||||
}
|
||||
}),
|
||||
tags: computed('group', {
|
||||
get(){
|
||||
return tagsToArray(this.get('group'), false);
|
||||
},
|
||||
set(key,value) {
|
||||
this.set('group', (value||[]).map((x) => normalizeTag(x)).join(', '));
|
||||
return value;
|
||||
}
|
||||
}),
|
||||
|
||||
hasTags(want) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
import { inject as service } from '@ember/service';
|
||||
import Resource from 'ember-api-store/models/resource';
|
||||
import PolledResource from 'ui/mixins/cattle-polled-resource';
|
||||
|
||||
var RancherKubernetesEngineConfig = Resource.extend(PolledResource, {
|
||||
type: 'rancherKubernetesEngineConfig',
|
||||
|
||||
reservedKeys: [],
|
||||
|
||||
actions: {
|
||||
deactivate() {
|
||||
return this.doAction('deactivate');
|
||||
},
|
||||
|
||||
activate() {
|
||||
return this.doAction('activate');
|
||||
},
|
||||
|
||||
edit: function() {
|
||||
},
|
||||
},
|
||||
|
||||
availableActions: function() {
|
||||
let a = this.get('actionLinks');
|
||||
let l = this.get('links');
|
||||
|
||||
return [
|
||||
{ label: 'action.edit', icon: 'icon icon-edit', action: 'edit', enabled: !!l.update },
|
||||
{ divider: true },
|
||||
{ label: 'action.activate', icon: 'icon icon-play', action: 'activate', enabled: !!a.activate , bulkable: true},
|
||||
{ label: 'action.deactivate', icon: 'icon icon-pause', action: 'deactivate', enabled: !!a.deactivate , bulkable: true},
|
||||
{ divider: true },
|
||||
{ label: 'action.remove', icon: 'icon icon-trash', action: 'promptDelete', enabled: !!l.remove, altAction: 'delete', bulkable: true },
|
||||
{ divider: true },
|
||||
{ label: 'action.viewInApi', icon: 'icon icon-external-link',action: 'goToApi', enabled: true },
|
||||
];
|
||||
}.property('actionLinks.{activate,deactivate,restore}','links.{update,remove}'),
|
||||
|
||||
});
|
||||
|
||||
export default RancherKubernetesEngineConfig;
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
import Stack from 'ui/models/namespace';
|
||||
|
||||
var StackConfiguration = Stack.extend();
|
||||
var StackConfiguration = Stack.extend({
|
||||
type: 'stackConfiguration'
|
||||
});
|
||||
|
||||
export default StackConfiguration;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@ Router.map(function() {
|
|||
// Clusters
|
||||
this.route('clusters', {path: '/clusters'}, function() {
|
||||
this.route('index', {path: '/'});
|
||||
this.route('new', {path: '/add'});
|
||||
this.route('new', {path: '/add'}, function() {
|
||||
this.route('rke');
|
||||
});
|
||||
this.route('new-project', {path: '/add-env'});
|
||||
this.route('project', {path: '/env/:project_id'});
|
||||
|
||||
|
|
|
|||
|
|
@ -245,11 +245,12 @@
|
|||
|
||||
|
||||
.border {
|
||||
|
||||
border: 1px solid $border;
|
||||
background: lighten($border, 2%);
|
||||
}
|
||||
|
||||
.border-dash {
|
||||
border: dashed $border;
|
||||
border: 1px dashed $border;
|
||||
background: lighten($border, 2%);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,18 @@
|
|||
background: $accent-border;
|
||||
}
|
||||
|
||||
.box-sm {
|
||||
padding: 75px 30px 30px 30px;
|
||||
min-height: 370px;
|
||||
position: relative;
|
||||
}
|
||||
.box {
|
||||
padding: 75px 40px 40px 40px;
|
||||
min-height: 410px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
.links {
|
||||
position: absolute;
|
||||
top: 300px;
|
||||
|
|
@ -48,7 +54,8 @@
|
|||
color: white;
|
||||
}
|
||||
|
||||
.box {
|
||||
.box,
|
||||
.box-sm {
|
||||
background-color: lighten($link-color, 40%);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
<div>
|
||||
<div class="row">
|
||||
<div class="col span-6">
|
||||
<label>{{t 'clustersPage.addPage.host.clusterName'}}{{field-required}}</label>
|
||||
{{input type="text" value=newHost.user }}
|
||||
</div>
|
||||
<div class="col span-6">
|
||||
<label>{{t 'clustersPage.addPage.host.hostName'}}{{field-required}}</label>
|
||||
{{input type="text" value=newHost.advertisedHostname }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-10 pb-15">
|
||||
<label>{{t 'clustersPage.addPage.host.ssh'}}{{field-required}}</label>
|
||||
{{textarea value=newHost.ssh classNames="form-control no-resize" rows="6"}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -5,7 +5,7 @@ module.exports = {
|
|||
// Return custom template variables here.
|
||||
return {
|
||||
// options are large-modal or medium-modal
|
||||
size: options.entity.options.size || 'medium-modal'
|
||||
size: options.size || 'medium-modal'
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ module.exports = {
|
|||
"no-useless-escape": 0,
|
||||
"ember/use-ember-get-and-set": 0,
|
||||
"ember/order-in-controllers": 0,
|
||||
"ember/order-in-models": 0,
|
||||
"ember/closure-actions": 0,
|
||||
"ember/order-in-components": 0,
|
||||
"ember/no-on-calls-in-components": 0,
|
||||
|
|
@ -77,6 +78,6 @@ module.exports = {
|
|||
"ember/use-brace-expansion": 0,
|
||||
"ember/no-side-effects": 0,
|
||||
"ember/no-capital-letters-in-routes": 0,
|
||||
"generator-star-spacing": 0,
|
||||
"generator-star-spacing": 0
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -42,18 +42,11 @@
|
|||
</li>
|
||||
{{/if}}
|
||||
|
||||
<li class="{{if (eq scope "clusters") 'active selected'}}">
|
||||
{{#link-to-external "authenticated.clusters"}}
|
||||
<i class="icon icon-cluster icon-fw"></i>
|
||||
{{t 'nav.environment.manage'}}
|
||||
{{/link-to-external}}
|
||||
</li>
|
||||
|
||||
{{#if (and isOwner projects.current)}}
|
||||
<li>{{#link-to-external "authenticated.clusters.project" projects.current.id class="clip"}}{{t 'nav.environment.edit' name=projects.current.displayName}}{{/link-to-external}}</li>
|
||||
<li role="presentation" class="divider"></li>
|
||||
{{/if}}
|
||||
|
||||
<li role="presentation" class="divider"></li>
|
||||
|
||||
{{#if projectIsMissing}}
|
||||
<li role="presentation" class="dropdown-header">{{t 'nav.environment.selected'}}</li>
|
||||
|
|
|
|||
|
|
@ -102,6 +102,10 @@
|
|||
</a>
|
||||
|
||||
<ul class="dropdown-menu dropdown-menu-right" data-dropdown-id="header-user-menu">
|
||||
<li class="{{if (eq scope "clusters") 'active selected'}}">
|
||||
{{#link-to-external "authenticated.clusters"}}{{t 'nav.environment.manage'}}{{/link-to-external}}
|
||||
</li>
|
||||
|
||||
{{#if accessEnabled}}
|
||||
<li role="presentation" class="user-auth">
|
||||
{{identity-block avatar=false identity=access.identity}}
|
||||
|
|
|
|||
|
|
@ -5,16 +5,4 @@ export default Component.extend({
|
|||
layout,
|
||||
model: null,
|
||||
tagName: '',
|
||||
expanded: null,
|
||||
|
||||
actions: {
|
||||
toggle() {
|
||||
this.sendAction('toggle');
|
||||
},
|
||||
|
||||
switchToProject(id) {
|
||||
// @TODO bad
|
||||
window.lc('authenticated').send('switchProject', id);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
<tr class="main-row">
|
||||
<td>
|
||||
<i role="button" {{action "toggle"}} class="icon icon-play eased text-small text-muted {{if expanded 'icon-rotate-90'}}"><span class="visually-hidden">Open accordion</span></i>
|
||||
</td>
|
||||
<td data-title="{{dt.state}}" class="state">
|
||||
{{badge-state model=model}}
|
||||
|
|
@ -62,22 +61,3 @@
|
|||
{{action-menu model=model}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="sub-row {{unless expanded 'hide'}}">
|
||||
<td>{{! expand}}</td>
|
||||
<td colspan="{{sub fullColspan 2}}">
|
||||
{{#if expanded}}
|
||||
{{project-table
|
||||
model=model.projects
|
||||
bulkActions=false
|
||||
search=false
|
||||
}}
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{{#if expanded}}
|
||||
<tr class="separator-row">
|
||||
<td colspan="{{fullColspan}}"></td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
import Component from '@ember/component';
|
||||
import ModalBase from 'shared/mixins/modal-base';
|
||||
import layout from './template';
|
||||
import { get/* , set */ } from '@ember/object';
|
||||
import { alias } from '@ember/object/computed';
|
||||
|
||||
export default Component.extend(ModalBase, {
|
||||
layout,
|
||||
classNames: ['small-modal'],
|
||||
newHost: alias('modalOpts.newHost'),
|
||||
list: alias('modalOpts.list'),
|
||||
actions: {
|
||||
add() {
|
||||
get(this, 'list').pushObject(get(this, 'newHost'));
|
||||
this.send('cancel');
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<div class="header clearfix">
|
||||
<h1>{{t 'clustersPage.newCluster'}}</h1>
|
||||
</div>
|
||||
<div>
|
||||
{{partial "add-cluster"}}
|
||||
</div>
|
||||
<div class="footer-actions">
|
||||
<button {{action 'add'}} class="btn bg-primary">{{t 'generic.save'}}</button>
|
||||
<button {{action "cancel"}} class="btn bg-primary">{{t 'modalWelcome.closeModal'}}</button>
|
||||
</div>
|
||||
|
|
@ -33,18 +33,11 @@
|
|||
</a>
|
||||
|
||||
<ul class="dropdown-menu cluster-menu" role="menu" data-dropdown-id="environment">
|
||||
<li class="{{if (eq scope "clusters") 'active selected'}}">
|
||||
{{#link-to "authenticated.clusters"}}
|
||||
<i class="icon icon-cluster icon-fw"></i>
|
||||
{{t 'nav.environment.manage'}}
|
||||
{{/link-to}}
|
||||
</li>
|
||||
|
||||
{{#if (and isOwner scope.current)}}
|
||||
<li>{{#link-to "authenticated.clusters.project" scope.current.id class="clip"}}{{t 'nav.environment.edit' name=scope.current.displayName}}{{/link-to}}</li>
|
||||
<li role="presentation" class="divider"></li>
|
||||
{{/if}}
|
||||
|
||||
<li role="presentation" class="divider"></li>
|
||||
|
||||
{{#if projectIsMissing}}
|
||||
<li role="presentation" class="dropdown-header">{{t 'nav.environment.selected'}}</li>
|
||||
|
|
|
|||
|
|
@ -102,6 +102,10 @@
|
|||
</a>
|
||||
|
||||
<ul class="dropdown-menu dropdown-menu-right" data-dropdown-id="header-user-menu">
|
||||
<li class="{{if (eq scope "clusters") 'active selected'}}">
|
||||
{{#link-to "authenticated.clusters"}}{{t 'nav.environment.manage'}}{{/link-to}}
|
||||
</li>
|
||||
|
||||
{{#if isAdmin}}
|
||||
<li class="">
|
||||
{{#link-to "global-admin"}}{{t 'nav.admin.tab' appName=settings.appName}}{{/link-to}}
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
export { default } from 'shared/components/modal-add-cluster/component';
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="2887.909 3543.104 127.082 130.651">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1, .cls-2, .cls-4, .cls-5 {
|
||||
fill: none;
|
||||
stroke: #3498db;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
|
||||
.cls-1, .cls-2, .cls-4 {
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
.cls-1 {
|
||||
stroke-width: 1.08px;
|
||||
}
|
||||
|
||||
.cls-3, .cls-6 {
|
||||
fill: #3498db;
|
||||
}
|
||||
|
||||
.cls-4, .cls-5 {
|
||||
stroke-width: 0.72px;
|
||||
}
|
||||
|
||||
.cls-6, .cls-7 {
|
||||
opacity: 0.1;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="environment-gke-01" transform="translate(2877.509 3527.844)">
|
||||
<path id="Path_6151" data-name="Path 6151" class="cls-1" d="M107.646,70.1l.121,37.192L75.421,125.948,75.3,88.757Z" transform="translate(13.724 11.482)"/>
|
||||
<path id="Path_6152" data-name="Path 6152" class="cls-1" d="M87.242,129.586,19.521,90.092,19.4,52.9,87.121,92.394Z" transform="translate(1.903 7.845)"/>
|
||||
<line id="Line_589" data-name="Line 589" class="cls-2" y2="36.344" transform="translate(105.257 91.759)"/>
|
||||
<path id="Path_6153" data-name="Path 6153" class="cls-3" d="M102.408,76.748l.121,26.652-23.26,13.326-.121-26.652,23.26-13.326m0-.848a.728.728,0,0,0-.485.121L78.785,89.347a1.02,1.02,0,0,0-.485.848l.121,26.652a.956.956,0,0,0,.969.969.728.728,0,0,0,.485-.121l23.26-13.326a.943.943,0,0,0,.363-.848V76.869a1.061,1.061,0,0,0-1.09-.969Z" transform="translate(14.358 12.709)"/>
|
||||
<path id="Path_6154" data-name="Path 6154" class="cls-3" d="M23.969,60.648l57.06,33.315.121,24.956L24.09,85.6l-.121-24.956m0-.848a.956.956,0,0,0-.969.969l.121,24.956a.915.915,0,0,0,.485.848l57.06,33.315a.84.84,0,0,0,1.211-.363c.121-.121.121-.242.121-.485V93.963a.915.915,0,0,0-.485-.848L24.454,59.921a.728.728,0,0,0-.485-.121Z" transform="translate(2.664 9.304)"/>
|
||||
<path id="Path_6155" data-name="Path 6155" class="cls-4" d="M100.885,77.2l.121,24.956L79.2,114.755" transform="translate(14.549 12.984)"/>
|
||||
<path id="Path_6156" data-name="Path 6156" class="cls-4" d="M67.265,85.875l-.121,23.139-2.544.606.121-25.32Z" transform="translate(11.461 14.485)"/>
|
||||
<path id="Path_6157" data-name="Path 6157" class="cls-4" d="M65.086,109.958,62.3,108.383V82.7" transform="translate(10.975 14.147)"/>
|
||||
<line id="Line_590" data-name="Line 590" class="cls-4" x1="5.573" y1="3.15" transform="translate(78.726 123.135)"/>
|
||||
<path id="Path_6158" data-name="Path 6158" class="cls-4" d="M58.644,80.975v23.139l-2.544.606V79.4Z" transform="translate(9.664 13.449)"/>
|
||||
<path id="Path_6159" data-name="Path 6159" class="cls-4" d="M56.586,105.058,53.8,103.483V77.8" transform="translate(9.177 13.111)"/>
|
||||
<line id="Line_591" data-name="Line 591" class="cls-4" x1="4.846" y1="2.786" transform="translate(68.429 117.442)"/>
|
||||
<line id="Line_592" data-name="Line 592" class="cls-4" x1="5.452" y1="3.15" transform="translate(57.526 111.142)"/>
|
||||
<path id="Path_6160" data-name="Path 6160" class="cls-4" d="M50.044,76.1l-.121,23.018L47.5,99.72V74.4Z" transform="translate(7.845 12.392)"/>
|
||||
<path id="Path_6161" data-name="Path 6161" class="cls-4" d="M48.008,100.058,45.1,98.483,45.221,72.8" transform="translate(7.338 12.053)"/>
|
||||
<path id="Path_6162" data-name="Path 6162" class="cls-4" d="M41.565,71.2l-.121,23.018L38.9,94.82l.121-25.32Z" transform="translate(6.027 11.355)"/>
|
||||
<path id="Path_6163" data-name="Path 6163" class="cls-4" d="M39.386,95.158,36.6,93.583,36.721,67.9" transform="translate(5.54 11.017)"/>
|
||||
<line id="Line_593" data-name="Line 593" class="cls-4" x1="4.846" y1="2.786" transform="translate(47.713 105.448)"/>
|
||||
<path id="Path_6164" data-name="Path 6164" class="cls-5" d="M33.044,66.2l-.121,23.018L30.5,89.82V64.5Z" transform="translate(4.25 10.298)"/>
|
||||
<path id="Path_6165" data-name="Path 6165" class="cls-5" d="M30.686,89.958,27.9,88.383,28.021,62.7" transform="translate(3.701 9.918)"/>
|
||||
<line id="Line_594" data-name="Line 594" class="cls-4" x1="4.846" y1="2.786" transform="translate(37.173 99.149)"/>
|
||||
<line id="Line_595" data-name="Line 595" class="cls-5" x1="5.33" y1="3.029" transform="translate(26.27 92.728)"/>
|
||||
<path id="Path_6166" data-name="Path 6166" class="cls-6" d="M137.482,104.646,89.145,132.631,10.4,85.142,20.94,78.6l-.121,6.421L88.66,124.393l31.74-19.02V97.014Z" transform="translate(0 13.28)"/>
|
||||
<g id="Group_5947" data-name="Group 5947" class="cls-7" transform="translate(77.515 52.992)">
|
||||
<path id="Path_6167" data-name="Path 6167" class="cls-3" d="M74.4,46.5,74.28,65.157,65.8,70.123V49.044" transform="translate(-65.8 -46.5)"/>
|
||||
</g>
|
||||
<path id="Path_6168" data-name="Path 6168" class="cls-6" d="M86.161,40.393V39.06a1.537,1.537,0,0,0-.121-.727c0-.242-.121-.485-.121-.727h0A5.247,5.247,0,0,0,85.8,37c0-.242-.121-.485-.121-.727V35.91a.445.445,0,0,0-.121-.363,1.722,1.722,0,0,0-.242-.727c0-.121-.121-.363-.121-.485v-.242c-.121-.242-.121-.485-.242-.727s-.121-.485-.242-.727V32.4c0-.121-.121-.242-.121-.485-.121-.242-.121-.485-.242-.727-.121-.121-.121-.363-.242-.485v-.242a2.047,2.047,0,0,1-.242-.606l-.363-.727V29a.119.119,0,0,0-.121-.121c-.121-.242-.242-.363-.242-.606l-.363-.727c-.121-.121-.121-.242-.242-.363a.119.119,0,0,0-.121-.121c-.121-.242-.242-.363-.363-.606-.242-.242-.363-.606-.606-.848a.119.119,0,0,0-.121-.121c-.242-.363-.606-.848-.848-1.211h0a5.13,5.13,0,0,1-.606-.848c-.121-.242-.363-.363-.485-.606h0c-.121-.242-.363-.363-.485-.606s-.363-.363-.485-.606a.119.119,0,0,0-.121-.121l-.121-.121-.363-.363L77.2,20.4a.423.423,0,0,0-.242-.121l-.121-.121c-.121-.121-.242-.121-.242-.242a2.127,2.127,0,0,0-.606-.485l-.242-.242-.121-.121c-.121,0-.121-.121-.242-.121-.242-.121-.363-.363-.606-.485a1.672,1.672,0,0,0-.485-.363h-.242c-.242-.121-.363-.242-.606-.363s-.363-.242-.606-.363a.119.119,0,0,1-.121-.121c-.121-.121-.242-.121-.485-.242s-.363-.242-.606-.242c-.121,0-.242-.121-.363-.121h-.242c-.242-.121-.363-.121-.606-.242s-.363-.121-.606-.242h-.242c-.121,0-.242-.121-.363-.121-.242,0-.363-.121-.606-.121h-.485c-.242,0-.363-.121-.606-.121H65.567c-.242,0-.485.121-.848.121H64.6c-.242.121-.485.121-.727.242h0a4.3,4.3,0,0,0-1.09.485L54.3,21.615a4.3,4.3,0,0,1,1.09-.485c.242-.121.606-.121.848-.242h.121a3.011,3.011,0,0,1,.969-.121h1.454c.363,0,.727.121,1.09.121h.121c.363.121.848.242,1.211.363h.121c.485.121.848.363,1.333.485h.121c.485.242.848.485,1.333.727a12.769,12.769,0,0,1,1.333.848h.121a8.488,8.488,0,0,1,1.211.969l.121.121a10.593,10.593,0,0,0,1.211.969l.121.121,1.09,1.09.121.121a12.063,12.063,0,0,0,1.211,1.333h0l1.09,1.454h0a12.69,12.69,0,0,0,.969,1.333c.242.242.363.606.606.848.121.242.363.485.485.727.121.121.121.242.242.363a13.214,13.214,0,0,1,.727,1.333.119.119,0,0,0,.121.121c.242.485.485,1.09.727,1.575v.121a8.412,8.412,0,0,1,.606,1.575v.121c.242.485.363,1.09.606,1.7v.121c.121.485.242,1.09.363,1.575v.121c.121.485.242,1.09.363,1.575h0c.121.485.121,1.09.242,1.575v.121c0,.485.121,1.09.121,1.575a5.9,5.9,0,0,1-.121,1.454v.121a5.152,5.152,0,0,1-.242,1.333v.121c-.121.363-.121.727-.242,1.09,0,.121,0,.121-.121.242-.121.363-.242.606-.363.969v.121a2.638,2.638,0,0,1-.606.969l-.121.121c-.121.242-.363.485-.485.727l-.242.242-.485.485-.242.242a5.128,5.128,0,0,1-.848.606l8.48-4.967c.242-.121.485-.363.848-.606l.242-.242.485-.485.242-.242a2.535,2.535,0,0,0,.485-.727l.121-.121h0a2.435,2.435,0,0,0,.485-.969h0v-.121c.121-.242.242-.363.242-.606,0-.121.121-.242.121-.363s0-.121.121-.242c0-.121,0-.121.121-.242a1.536,1.536,0,0,0,.121-.727v-.606a5.247,5.247,0,0,1,.121-.606V41.12h0A1.537,1.537,0,0,0,86.161,40.393Z" transform="translate(9.283)"/>
|
||||
<g id="Group_5948" data-name="Group 5948" transform="translate(59.343 20.351)">
|
||||
<path id="Path_6169" data-name="Path 6169" class="cls-1" d="M64.611,21.426C72.243,25.788,78.3,36.448,78.3,45.171c0,6.905-3.877,10.54-9.328,9.571V75.821l-12.72-7.269,3.513-2.059-3.513-6.057,3.513-2.059-3.513-6.057,3.756-2.181v-.485C54.677,44.444,50.8,36.327,50.8,29.422,50.8,20.578,56.978,17.065,64.611,21.426Zm0,12.841C66.428,35.358,68,34.51,68,32.329a7.211,7.211,0,0,0-3.392-5.815c-1.817-1.09-3.392-.242-3.392,1.938a7.389,7.389,0,0,0,3.392,5.815" transform="translate(-50.8 -19.557)"/>
|
||||
</g>
|
||||
<path id="Path_6170" data-name="Path 6170" class="cls-1" d="M66.647,46.344,51.14,37.5,19.4,56.035,87.121,95.65l32.346-18.657L84.213,56.4" transform="translate(1.903 4.589)"/>
|
||||
<path id="Path_6171" data-name="Path 6171" class="cls-3" d="M72.8,63.782l8.844-5.573L72.8,53Z" transform="translate(13.195 7.866)"/>
|
||||
<g id="Group_5949" data-name="Group 5949" transform="translate(77.515 52.992)">
|
||||
<path id="Path_6172" data-name="Path 6172" class="cls-1" d="M74.4,46.5,74.28,65.157,65.8,70.123V49.044" transform="translate(-65.8 -46.5)"/>
|
||||
</g>
|
||||
<path id="Path_6173" data-name="Path 6173" class="cls-1" d="M86.161,40.393V39.06a1.537,1.537,0,0,0-.121-.727c0-.242-.121-.485-.121-.727h0A5.247,5.247,0,0,0,85.8,37c0-.242-.121-.485-.121-.727V35.91a.445.445,0,0,0-.121-.363,1.722,1.722,0,0,0-.242-.727c0-.121-.121-.363-.121-.485v-.242c-.121-.242-.121-.485-.242-.727s-.121-.485-.242-.727V32.4c0-.121-.121-.242-.121-.485-.121-.242-.121-.485-.242-.727-.121-.121-.121-.363-.242-.485v-.242a2.047,2.047,0,0,1-.242-.606l-.363-.727V29a.119.119,0,0,0-.121-.121c-.121-.242-.242-.363-.242-.606l-.363-.727c-.121-.121-.121-.242-.242-.363a.119.119,0,0,0-.121-.121c-.121-.242-.242-.363-.363-.606-.242-.242-.363-.606-.606-.848a.119.119,0,0,0-.121-.121c-.242-.363-.606-.848-.848-1.211h0a5.13,5.13,0,0,1-.606-.848c-.121-.242-.363-.363-.485-.606h0c-.121-.242-.363-.363-.485-.606s-.363-.363-.485-.606a.119.119,0,0,0-.121-.121l-.121-.121-.363-.363L77.2,20.4a.423.423,0,0,0-.242-.121l-.121-.121c-.121-.121-.242-.121-.242-.242a2.127,2.127,0,0,0-.606-.485l-.242-.242-.121-.121c-.121,0-.121-.121-.242-.121-.242-.121-.363-.363-.606-.485a1.672,1.672,0,0,0-.485-.363h-.242c-.242-.121-.363-.242-.606-.363s-.363-.242-.606-.363a.119.119,0,0,1-.121-.121c-.121-.121-.242-.121-.485-.242s-.363-.242-.606-.242c-.121,0-.242-.121-.363-.121h-.242c-.242-.121-.363-.121-.606-.242s-.363-.121-.606-.242h-.242c-.121,0-.242-.121-.363-.121-.242,0-.363-.121-.606-.121h-.485c-.242,0-.363-.121-.606-.121H65.567c-.242,0-.485.121-.848.121H64.6c-.242.121-.485.121-.727.242h0a4.3,4.3,0,0,0-1.09.485L54.3,21.615a4.3,4.3,0,0,1,1.09-.485c.242-.121.606-.121.848-.242h.121a3.011,3.011,0,0,1,.969-.121h1.454c.363,0,.727.121,1.09.121h.121c.363.121.848.242,1.211.363h.121c.485.121.848.363,1.333.485h.121c.485.242.848.485,1.333.727a12.769,12.769,0,0,1,1.333.848h.121a8.488,8.488,0,0,1,1.211.969l.121.121a10.593,10.593,0,0,0,1.211.969l.121.121,1.09,1.09.121.121a12.063,12.063,0,0,0,1.211,1.333h0l1.09,1.454h0a12.69,12.69,0,0,0,.969,1.333c.242.242.363.606.606.848.121.242.363.485.485.727.121.121.121.242.242.363a13.214,13.214,0,0,1,.727,1.333.119.119,0,0,0,.121.121c.242.485.485,1.09.727,1.575v.121a8.412,8.412,0,0,1,.606,1.575v.121c.242.485.363,1.09.606,1.7v.121c.121.485.242,1.09.363,1.575v.121c.121.485.242,1.09.363,1.575h0c.121.485.121,1.09.242,1.575v.121c0,.485.121,1.09.121,1.575a5.9,5.9,0,0,1-.121,1.454v.121a5.152,5.152,0,0,1-.242,1.333v.121c-.121.363-.121.727-.242,1.09,0,.121,0,.121-.121.242-.121.363-.242.606-.363.969v.121a2.638,2.638,0,0,1-.606.969l-.121.121c-.121.242-.363.485-.485.727l-.242.242-.485.485-.242.242a5.128,5.128,0,0,1-.848.606l8.48-4.967c.242-.121.485-.363.848-.606l.242-.242.485-.485.242-.242a2.535,2.535,0,0,0,.485-.727l.121-.121h0a2.435,2.435,0,0,0,.485-.969h0v-.121c.121-.242.242-.363.242-.606,0-.121.121-.242.121-.363s0-.121.121-.242c0-.121,0-.121.121-.242a1.536,1.536,0,0,0,.121-.727v-.606a5.247,5.247,0,0,1,.121-.606V41.12h0A1.537,1.537,0,0,0,86.161,40.393Z" transform="translate(9.283)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
|
@ -7,6 +7,7 @@ languageContribute: "Help Translate Rancher"
|
|||
generic:
|
||||
actions: Actions
|
||||
activate: Activate
|
||||
add: Add
|
||||
all: All
|
||||
any: Any
|
||||
as: as
|
||||
|
|
@ -457,15 +458,10 @@ certificatesPage:
|
|||
placeholder: e.g. EV cert for mydomain.com
|
||||
|
||||
clustersPage:
|
||||
header: Clusters & Environments
|
||||
header: Clusters
|
||||
newCluster: Add Cluster
|
||||
newProject: Add Environment
|
||||
import: Import External
|
||||
newHost: Add Host
|
||||
alert: There are no active environments. You will need to create or activate one before you can do anything else.
|
||||
mode:
|
||||
list: Environment List
|
||||
grouped: Grouped by Cluster
|
||||
subtext: |
|
||||
<h4>{appName} supports grouping resources into multiple <b class="text-info">clusters</b> and <b class="text-info">environments</b>.</h4>
|
||||
<div class="row">
|
||||
|
|
@ -488,6 +484,44 @@ clustersPage:
|
|||
label: RAM
|
||||
storage:
|
||||
label: Disk
|
||||
indexPage:
|
||||
rke:
|
||||
header: Create a RKE Cluster
|
||||
desc: Rancher automatically deploys and manages Kubernetes.
|
||||
cloud:
|
||||
header: Create a Cloud Cluster
|
||||
desc: Create and use a new cluster with in a cloud provider.
|
||||
import:
|
||||
header: Import Existing Cluster
|
||||
desc: Deploy containers into an existing Kubernetes installation using hosts and networking it provides.
|
||||
|
||||
|
||||
addPage:
|
||||
host:
|
||||
clusterName: User
|
||||
hostName: Host Name
|
||||
ssh: SSH Key
|
||||
rke:
|
||||
header: |
|
||||
{count, plural,
|
||||
=1 {Add RKE: Step # set up your ETCD hosts.}
|
||||
=2 {Add RKE: Step # Add Managment hosts.}
|
||||
=3 {Add RKE: Step # Add Nodes Hosts.}
|
||||
}
|
||||
reuse:
|
||||
radioLabel: Specify your existing ETCD cluster
|
||||
nodes: Reuse other nodes
|
||||
management: Use for Managment
|
||||
useNode: Use as Node
|
||||
new:
|
||||
radioLabel: Add new cluster
|
||||
minimums:
|
||||
cluster: Minimum 1 host. 3 hosts recommended.
|
||||
nocluster: You have no hosts. Minimum 1 host. 3 hosts recommended.
|
||||
management: Minimum 1 host. 2 hosts recommended.
|
||||
noManagement: You have no management nodes. Minimum 1 host. 3 hosts recommended.
|
||||
nodes: Minimum 1 host.
|
||||
noNodes: You have no hosts. Minimum 1 host.
|
||||
|
||||
containerPage:
|
||||
header: 'Container: {name}'
|
||||
|
|
|
|||
Loading…
Reference in New Issue