Merge pull request #1198 from vincent99/master

Bugs
This commit is contained in:
Vincent Fiduccia 2017-05-29 14:36:55 -07:00 committed by GitHub
commit d1a018e93a
34 changed files with 259 additions and 182 deletions

View File

@ -14,6 +14,6 @@
expanded=(array-includes expandedStacks stack.id)
}}
{{else}}
<h1>You should add a catalog item...</h1>
{{empty-table resource="container" newRoute="catalog-tab" newTranslationKey="nav.apps.launch"}}
{{/each}}
</section>

View File

@ -50,6 +50,10 @@ export default Ember.Component.extend(ManageLabels, {
}
},
updateLabels(labels) {
this.sendAction('setLabels', labels);
},
// ----------------------------------
// Capability
// ----------------------------------
@ -81,7 +85,7 @@ export default Ember.Component.extend(ManageLabels, {
memoryMode: 'unlimited', // unlimited, set
memoryMb: null,
swapMode: 'default', // default, none, unlimited, set
swappinesMode: 'default', // default, min, set
swappinessMode: 'default', // default, none, set
swapMb: null,
memoryReservationMb: null,
initMemory: function() {
@ -89,7 +93,6 @@ export default Ember.Component.extend(ManageLabels, {
var memPlusSwapBytes = this.get('instance.memorySwap') || 0;
var swapBytes = Math.max(0, memPlusSwapBytes - memBytes);
var memReservation = this.get('instance.memoryReservation');
var swappiness = this.get('instance.memorySwappiness');
if (memReservation) {
this.set('memoryReservationMb', parseInt(memReservation,10)/1048576);
@ -129,6 +132,11 @@ export default Ember.Component.extend(ManageLabels, {
}
}
var swappiness = this.get('instance.memorySwappiness');
if ( swappiness ) {
swappiness = parseInt(swappiness,10);
}
if ( this.get('swapMode') === 'none' || swappiness === null || swappiness === undefined ) {
this.set('instance.memorySwappiness', null);
this.set('swappinessMode','default');
@ -139,28 +147,51 @@ export default Ember.Component.extend(ManageLabels, {
this.set('instance.memorySwappiness', swappiness);
this.set('swappinessMode', 'set');
}
this.updateMemory();
},
memoryDidChange: function() {
updateMemory: function() {
// The actual parameter we're interested in is 'memory', in bytes.
let mem = parseInt(this.get('memoryMb'),10);
let swap = parseInt(this.get('swapMb'),10);
let memoryMode = this.get('memoryMode');
let swapMode = this.get('swapMode');
let swappinessMode = this.get('swappinessMode');
let swappiness = this.get('swappiness');
// Swappiness
if ( swappinessMode === 'default' ) {
this.set('instance.memorySwappiness', null);
} else if ( swappinessMode === 'min' ) {
this.set('instance.memorySwappiness', 0);
} else {
if ( swappiness ) {
swappiness = parseInt(swappiness,10);
}
if ( isNaN(swappiness) || !swappiness ) {
swappiness = 50;
this.set('swappiness', swappiness);
return; // We'll be back
}
this.set('instance.memorySwappiness', swappiness);
}
// Memory
if ( memoryMode === 'unlimited' || isNaN(mem) || mem <= 0) {
this.setProperties({
'instance.memory': null,
'instance.memorySwap': null,
'swapMode': 'unlimited',
'swappinessMode': 'set',
'instance.memorySwappiness': 0,
});
return;
}
this.set('instance.memory', mem * 1048576);
// Swap
switch (swapMode) {
case 'default':
this.set('instance.memorySwap', null);
@ -171,22 +202,23 @@ export default Ember.Component.extend(ManageLabels, {
break;
case 'none':
this.set('instance.memorySwap', mem*1048576);
this.set('swappinessMode', 'min');
this.set('instance.memorySwappiness', 0);
break;
case 'set':
this.set('instance.memorySwap', (mem+swap)*1048576);
break;
}
}.observes('memoryMb','memoryMode','swapMb','swapMode'),
},
memoryDidChange: function() {
Ember.run.next(this,'updateMemory');
}.observes('memoryMb','memoryMode','swapMb','swapMode','swappinessMode','swappiness'),
memoryReservationChanged: Ember.observer('memoryReservationMb', function() {
var mem = this.get('memoryReservationMb');
if ( isNaN(mem) || mem <= 0) {
this.set('instance.memoryReservation', null);
}
else {
} else {
this.set('instance.memoryReservation', mem * 1048576);
}
}),

View File

@ -275,6 +275,17 @@ export default Ember.Component.extend(NewOrEdit, SelectTab, {
return ok;
},
doSave() {
if ( this.get('isService') || !this.get('isUpgrade') ) {
return this._super(...arguments);
}
// Container upgrade
return this.get('primaryResource').doAction('upgrade', {
config: this.get('primaryResource')
});
},
didSave() {
if ( this.get('isService') ) {
// Returns a promise

View File

@ -133,7 +133,8 @@ export default Ember.Component.extend(NewOrEdit, {
}.observes(
'userLabels.@each.{key,value}',
'scaleLabels.@each.{key,value}',
'schedulingLabels.@each.{key,value}'
'schedulingLabels.@each.{key,value}',
'stickinessLabels.@each.{key,value}'
),
mergeLabels() {
@ -145,6 +146,7 @@ export default Ember.Component.extend(NewOrEdit, {
(this.get('userLabels')||[]).forEach((row) => { out[row.key] = row.value; });
(this.get('scaleLabels')||[]).forEach((row) => { out[row.key] = row.value; });
(this.get('schedulingLabels')||[]).forEach((row) => { out[row.key] = row.value; });
(this.get('stickinessLabels')||[]).forEach((row) => { out[row.key] = row.value; });
var config = this.get('launchConfig');
if ( config )

View File

@ -52,12 +52,10 @@
setLabels=(action 'setLabels' 'scheduling')
}}
{{#liquid-if service.lbConfig.needsCertificate}}
{{form-ssl-termination
service=service
allCertificates=allCertificates
}}
{{/liquid-if}}
{{form-ssl-termination
service=service
allCertificates=allCertificates
}}
{{#advanced-section advanced=false}}
{{#accordion-list as | al expandFn | }}
@ -75,6 +73,8 @@
}}
{{form-stickiness
initialLabels=launchConfig.labels
setLabels=(action 'setLabels' 'stickiness')
service=service
expandAll=al.expandAll
expandFn=expandFn

View File

@ -70,7 +70,7 @@ export default Ember.Component.extend({
validate() {
var errors = [];
var globals = ['all', 'community', 'library']; // these should be removed when these terms are removed from the envid field
var global = this.get('global');
var ary = this.get('ary');
ary.forEach((cat) => {
@ -82,7 +82,8 @@ export default Ember.Component.extend({
errors.push('URL is required on each catalog');
}
if (globals.indexOf(cat.name.toLowerCase()) >= 0 || ary.filter((x) => (x.name||'').trim().toLowerCase() === cat.name.toLowerCase()).length > 1) {
if ( global.filter((x) => (x.name||'').trim().toLowerCase() === cat.name.toLowerCase()).length > 1 ||
ary.filter((x) => (x.name||'').trim().toLowerCase() === cat.name.toLowerCase()).length > 1) {
errors.push('Each catalog must have a unique name');
}
});

View File

@ -8,7 +8,6 @@ export default Ember.Component.extend({
ports: null,
protocolChoices: null,
showBackend: null,
errors: null,
onInit: function() {
@ -67,11 +66,6 @@ export default Ember.Component.extend({
protos.removeObject('udp');
protos.sort();
this.set('protocolChoices', protos);
if ( this.get('showBackend') === null ) {
let hasName = !!rules.findBy('backendName');
this.set('showBackend', hasName);
}
}.on('init'),
shouldFlattenAndValidate: function() {
@ -196,10 +190,6 @@ export default Ember.Component.extend({
this.get('ports').removeObject(port);
},
showBackend() {
this.set('showBackend', true);
},
rulesChanged() {
this.shouldFlattenAndValidate();
},

View File

@ -6,13 +6,6 @@
<span class="darken"><i class="icon icon-plus text-small"></i></span>
<span>{{t 'formBalancerListeners.addPortLabel'}}</span>
</button>
{{#unless showBackend}}
<div class="pull-right clearfix">
<button class="btn bg-transparent text-small inline-block" {{action "showBackend"}}>
{{t 'formBalancerListeners.showBackendLabel'}}
</button>
</div>
{{/unless}}
</div>
</div>
<hr/>
@ -63,7 +56,6 @@
protocol=port.protocol
rulesChanged=(action 'rulesChanged')
singleTarget=false
showBackend=showBackend
editing=true
}}
<div class="clearfix">

View File

@ -5,9 +5,18 @@ export default Ember.Component.extend({
singleTarget: true,
protocol: null,
editing: true,
showBackend: null,
ruleType: 'portRule',
didReceiveAttrs() {
this._super(...arguments);
if ( this.get('showBackend') !== true ) {
let hasName = !!((this.get('rules')||[]).findBy('backendName'));
this.set('showBackend', hasName);
}
},
rulesChanged: function() {
this.sendAction('rulesChanged');
}.observes('rules.@each.{hostname,path,kind,instanceId,serviceId,selector,targetPort,backendName}'),
@ -55,6 +64,10 @@ export default Ember.Component.extend({
removeRule(rule) {
this.get('rules').removeObject(rule);
},
showBackend() {
this.set('showBackend', true);
},
},
protocolChanged: function() {

View File

@ -116,6 +116,13 @@
{{/each}}
</tbody>
</table>
{{#unless showBackend}}
<div class="pull-right clearfix">
<button class="btn bg-transparent p-0 pl-20 text-small inline-block" {{action "showBackend"}}>
{{t 'formBalancerListeners.showBackendLabel'}}
</button>
</div>
{{/unless}}
{{else}}
<span class="text-muted">{{t 'formBalancerRules.noRules'}}</span>
{{/if}}

View File

@ -47,7 +47,6 @@ export default Ember.Component.extend({
showUriHost: Ember.computed.equal('uriVersion', HTTP_1_1),
strategy: null,
quorum: null,
actions: {
chooseUriMethod(method) {
@ -96,7 +95,6 @@ export default Ember.Component.extend({
this.setProperties({
strategy: this.get('healthCheck.strategy') || 'recreate',
quorum: this.get('healthCheck.recreateOnQuorumStrategyConfig.quorum') || '1',
});
}
else
@ -108,7 +106,6 @@ export default Ember.Component.extend({
uriVersion: HTTP_1_0,
uriHost: '',
strategy: 'recreate',
quorum: '1',
});
}
@ -164,27 +161,8 @@ export default Ember.Component.extend({
var strategy = this.get('strategy');
var hc = this.get('healthCheck');
if ( strategy === 'recreateOnQuorum' )
{
hc.setProperties({
'strategy': strategy,
'recreateOnQuorumStrategyConfig': {
quorum: parseInt(this.get('quorum'),10),
},
});
}
else
{
hc.setProperties({
'strategy': strategy,
'recreateOnQuorumStrategyConfig': null,
});
}
}.observes('strategy','quorum'),
quorumDidChange: function() {
this.set('strategy', 'recreateOnQuorum');
}.observes('quorum'),
hc.set('strategy', strategy);
}.observes('strategy'),
validate: function() {
var errors = [];

View File

@ -159,16 +159,6 @@
<div class="radio">
<label>{{radio-button selection=strategy value="recreate"}} {{t 'formHealthCheck.strategy.recreate'}}</label>
</div>
<div class="radio">
<label>
{{radio-button selection=strategy value="recreateOnQuorum"}}
<span class="with-input">
{{t 'formHealthCheck.strategy.recreateOnQuorumPrefix' quorum=quorum}}
{{input-integer min=1 safeStyle="width: 60px; display: inline-block;" class="form-control input-xs" value=quorum}}
{{t 'formHealthCheck.strategy.recreateOnQuorumSuffix' quorum=quorum}}
</span>
</label>
</div>
{{/input-or-display}}
{{/if}}
{{/if}}

View File

@ -7,76 +7,79 @@
expand=(action expandFn)
}}
{{#if allCertificates.length}}
<div class="row inline-form">
<div class="col span-2 col-inline">
<label>{{t 'formSslTermination.certificate'}}</label>
{{#liquid-if service.lbConfig.needsCertificate}}
{{#if allCertificates.length}}
<div class="row inline-form">
<div class="col span-2 col-inline">
<label>{{t 'formSslTermination.certificate'}}{{field-required}}</label>
</div>
<div class="col span-8">
{{new-select
classNames="form-control"
prompt=(t 'formSslTermination.defaultCertificate.prompt')
content=allCertificates
optionLabelPath="displayDetailedName"
optionValuePath="id"
value=lbConfig.defaultCertificateId
}}
</div>
</div>
<div class="col span-8">
{{new-select
classNames="form-control"
prompt=(t 'formSslTermination.defaultCertificate.prompt')
content=allCertificates
optionLabelPath="displayDetailedName"
optionValuePath="id"
value=lbConfig.defaultCertificateId
}}
</div>
</div>
<div class="row inline-form">
<div class="col span-2 col-inline">
<label>{{t 'formSslTermination.alternateCerts'}}</label>
</div>
<div class="col span-8">
<table class="table fixed no-lines no-top-padding">
<thead>
<tr>
<td>
{{#if alternateCertificates.length}}
<button class="btn bg-link icon-btn" {{action "addAlternate"}}>
<span class="darken"><i class="icon icon-plus text-small"/></span>
<span>{{t 'formSslTermination.addAlternate'}}</span>
</button>
{{else}}
<span class="text-muted">{{t 'formSslTermination.noAlternateCertificates'}}</span>
{{/if}}
</td>
<th width="30">&nbsp;</th>
</tr>
</thead>
<tbody>
{{#each alternates as |alt|}}
<div class="row inline-form">
<div class="col span-2 col-inline">
<label>{{t 'formSslTermination.alternateCerts'}}</label>
</div>
<div class="col span-8">
<table class="table fixed no-lines no-top-padding">
<thead>
<tr>
<td>
{{new-select
classNames="form-control"
prompt=(t 'formSslTermination.alternateCertificate.prompt')
content=alternateCertificates
optionLabelPath="displayDetailedName"
optionValuePath="id"
value=alt.value
}}
</td>
<td class="text-right">
{{#unless link.existing}}
<button class="btn bg-primary btn-sm" {{action "removeAlternate" alt}}><i class="icon icon-minus"/></button>
{{/unless}}
{{#if alternateCertificates.length}}
<button class="btn bg-link icon-btn" {{action "addAlternate"}}>
<span class="darken"><i class="icon icon-plus text-small"/></span>
<span>{{t 'formSslTermination.addAlternate'}}</span>
</button>
{{else}}
<span class="text-muted">{{t 'formSslTermination.noAlternateCertificates'}}</span>
{{/if}}
</td>
<th width="30">&nbsp;</th>
</tr>
{{/each}}
</tbody>
</table>
</thead>
<tbody>
{{#each alternates as |alt|}}
<tr>
<td>
{{new-select
classNames="form-control"
prompt=(t 'formSslTermination.alternateCertificate.prompt')
content=alternateCertificates
optionLabelPath="displayDetailedName"
optionValuePath="id"
value=alt.value
}}
</td>
<td class="text-right">
{{#unless link.existing}}
<button class="btn bg-primary btn-sm" {{action "removeAlternate" alt}}><i class="icon icon-minus"/></button>
{{/unless}}
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
</div>
<div class="row inline-form">
<div class="offset-2 col offset-8">
<p class="text-info">{{t 'formSslTermination.helpBlock' htmlSafe=true}}</p>
<div class="row inline-form">
<div class="offset-2 col offset-8">
<p class="text-info">{{t 'formSslTermination.helpBlock' htmlSafe=true}}</p>
</div>
</div>
</div>
{{else}}
<span class="text-muted">{{t 'formSslTermination.noCertificates'}}</span>
{{/if}}
{{else}}
<span class="text-muted">{{t 'formSslTermination.noCertificates'}}</span>
{{/if}}
<span class="text-muted">{{t 'formSslTermination.notNeeded'}}</span>
{{/liquid-if}}
{{/accordion-list-item}}

View File

@ -1,7 +1,9 @@
import Ember from 'ember';
import { STATUS, STATUS_INTL_KEY, classForStatus } from 'ui/components/accordion-list-item/component';
import C from 'ui/utils/constants';
import ManageLabels from 'ui/mixins/manage-labels';
export default Ember.Component.extend({
export default Ember.Component.extend(ManageLabels, {
service : null,
intl: Ember.inject.service(),
@ -38,12 +40,20 @@ export default Ember.Component.extend({
});
}
this.initLabels(this.get('initialLabels'), null, C.LABEL.BALANCER_TARGET);
var target = this.getLabel(C.LABEL.BALANCER_TARGET)||'any';
this.setProperties({
policy: policy,
stickiness: stickiness,
balancerTarget: target,
});
},
updateLabels(labels) {
this.sendAction('setLabels', labels);
},
stickinessDidChange: function() {
var stickiness = this.get('stickiness');
if ( !this.get('lbConfig.canSticky') || stickiness === 'none' )
@ -56,6 +66,15 @@ export default Ember.Component.extend({
}
}.observes('stickiness','lbConfig.canSticky'),
balancerTargetDidChange: function() {
let target = this.get('balancerTarget');
if ( target === 'any' ) {
this.removeLabel(C.LABEL.BALANCER_TARGET, true);
} else {
this.setLabel(C.LABEL.BALANCER_TARGET, target);
}
}.observes('balancerTarget'),
statusClass: null,
status: function() {
let k = STATUS.NOTCONFIGURED;

View File

@ -6,6 +6,21 @@
expandAll=expandAll
expand=(action expandFn)
}}
<label>{{t 'formStickiness.balancerTarget'}}</label>
<div class="radio">
<label>{{radio-button selection=balancerTarget value="any"}} {{t 'formStickiness.any' htmlSafe=true}}</label>
</div>
<div class="radio">
<label>{{radio-button selection=balancerTarget value="prefer-local"}} {{t 'formStickiness.preferLocal' htmlSafe=true}}</label>
</div>
<div class="radio">
<label>{{radio-button selection=balancerTarget value="only-local"}} {{t 'formStickiness.onlyLocal' htmlSafe=true}}</label>
</div>
<hr/>
<label>{{t 'formStickiness.sticky'}}</label>
{{#liquid-if lbConfig.canSticky}}
<div class="row {{unless isNone 'inline-form'}}">
<div class="col span-2 radio">
@ -62,5 +77,7 @@
</div>
</div>
{{/liquid-if}}
{{else}}
<span class="text-muted">{{t 'formStickiness.noPorts'}}</span>
{{/liquid-if}}
{{/accordion-list-item}}

View File

@ -78,7 +78,7 @@
{{/each}}
{{else}}
{{#each groupedInstances as |group|}}
{{#if (or showAdd group.instances.length)}}
{{#if group.instances.length}}
<div class="container-subpod-info">
<div class="subpod-header">
<h6 class="clip">
@ -99,19 +99,13 @@
{{#each group.instances as |item|}}
{{container-subpod model=item.main children=item.children}}
{{/each}}
{{#unless group.name}}
{{#if showAdd}}
{{add-subpod action="newContainer" label="hostsPage.addContainer" groupHasChildren=group.hasChildren}}
{{/if}}
{{/unless}}
</div>
</div>
{{/if}}
{{else}}
{{#if showAdd}}
{{add-subpod action="newContainer" label="hostsPage.addContainer" groupHasChildren=group.hasChildren}}
{{/if}}
{{/each}}
{{#if showAdd}}
{{add-subpod action="newContainer" label="hostsPage.addContainer" groupHasChildren=group.hasChildren}}
{{/if}}
{{/if}}
</div>
{{/if}}

View File

@ -167,9 +167,8 @@ export default Ember.Component.extend(NewOrEdit, {
item.answer = item.default;
}
});
return response;
}
return response;
});
this.set('selectedTemplateModel', selectedTemplateModel);

View File

@ -39,7 +39,7 @@ export default Ember.Component.extend({
let map = {};
// Start with ours, then load the users in case they override the value
if (this.get('enableLibrary')) {
map[C.CATALOG.LIBRARY_KEY] = {url: C.CATALOG.LIBRARY_VALUE, branch: def};
map[C.CATALOG.LIBRARY_KEY] = {url: C.CATALOG.LIBRARY_VALUE, branch: C.CATALOG.LIBRARY_BRANCH};
}
if (this.get('enableCommunity')) {
@ -79,7 +79,7 @@ export default Ember.Component.extend({
let library = false;
let entry = map[C.CATALOG.LIBRARY_KEY];
if ( entry && entry.url === C.CATALOG.LIBRARY_VALUE && entry.branch === def ) {
if ( entry && entry.url === C.CATALOG.LIBRARY_VALUE && entry.branch === C.CATALOG.LIBRARY_BRANCH ) {
library = true;
delete map[C.CATALOG.LIBRARY_KEY];
}

View File

@ -6,6 +6,7 @@ const ALLOWED = {
'access.log': {description: 'Path to write access logs to (HA installation only)'},
'api.auth.jwt.token.expiry': {description: 'Authorization token/UI session lifetime (milliseconds)', kind: 'int'},
'api.auth.realm': {description: 'HTTP Basic Auth realm for requests without Authorization header'},
'api.auth.restrict.concurrent.sessions': {description: 'Limit active session tokens to one per account. This mainly prevents users from logging in to the UI from multiple computers simultaneously. Note: Existing sessions may continue to be valid until they expire when this is initially enabled.', kind: 'boolean'},
'api.interceptor.config': {description: 'JSON configuration for API Interceptor', kind: 'multiline'},
'api.proxy.allow': {description: 'Allow use of /v1/proxy to talk to whitelisted domains, for custom Add Host UIs', kind: 'boolean'},
'api.proxy.whitelist': {description: 'Whitelist of domains to that can be proxied through /v1/proxy to, for custom Add Host UIs'},
@ -38,7 +39,7 @@ const ALLOWED = {
'ui.sendgrid.template.password_reset': {description: 'SendGrid template for initiating password reset', mode: C.MODE.CAAS},
'ui.sendgrid.template.create_user': {description: 'SendGrid template for confirming email', mode: C.MODE.CAAS},
'ui.sendgrid.template.verify_password': {description: 'SendGrid template for confirming password reset', mode: C.MODE.CAAS},
'upgrade.manager': {description: 'Automatic upgrades of infrastructure stacks', kind: 'boolean'},
'upgrade.manager': {description: 'Automatic upgrades of infrastructure stacks', kind: 'enum', options: ['all','mandatory','none']},
};
export default Ember.Component.extend({

View File

@ -16,7 +16,7 @@ export default Ember.Route.extend({
if ( params.upgrade )
{
return Ember.Object.create({
instance: instance,
instance: results.existing.clone(),
});
}

View File

@ -1,5 +1,5 @@
{{container/new-edit
isUpgrade=isUpgrade
isUpgrade=upgrade
isService=false
launchConfig=model.instance
primaryResource=model.instance

View File

@ -20,7 +20,7 @@ const defaultStateMap = {
'initializing': {icon: 'icon icon-alert', color: 'text-warning'},
'migrating': {icon: 'icon icon-info', color: 'text-info' },
'provisioning': {icon: 'icon icon-circle', color: 'text-info' },
'garbage-collection': {icon: 'icon icon-trash', color: 'text-success'},
'pending-delete': {icon: 'icon icon-trash', color: 'text-muted' },
'purged': {icon: 'icon icon-purged', color: 'text-error' },
'purging': {icon: 'icon icon-purged', color: 'text-info' },
'reconnecting': {icon: 'icon icon-alert', color: 'text-error' },

View File

@ -87,6 +87,11 @@ export default Ember.Mixin.create({
}
remaining.removeObjects(related);
} else if ( stackId ) {
let unit = getOrCreateUnit(groupId, groupName, instance.get('id'));
unit.group.hasChildren = false;
unit.main = instance;
remaining.removeObject(instance);
} else {
orphans = [instance];
}

View File

@ -16,6 +16,10 @@ export default Ember.Mixin.create({
this.get(inputKey).sortBy('stateSort').forEach((inst) => {
let color = inst.get('stateBackground');
if ( color === 'bg-muted' ) {
color = 'bg-success';
}
let state = inst.get('displayState');
let entry = byName.findBy('state', state);
if ( entry ) {
@ -42,7 +46,7 @@ export default Ember.Mixin.create({
this.set(sortProperty, Ember.computed(countsProperty, `${inputKey}.[]`, () => {
let colors = this.get(`${countsProperty}.byColor`);
let success = (colors.findBy('bg-success')||{}).count;
let success = (colors.findBy('bg-success')||{}).count + (colors.findBy('bg-muted')||{}).coun;
let error = (colors.findBy('bg-error')||{}).count;
let other = this.get(`${inputKey}.length`) - success - error;

View File

@ -143,8 +143,8 @@ var Container = Instance.extend({
var health = this.get('healthState');
var hasCheck = !!this.get('healthCheck');
if ( this.get('desired') === false ) {
return 'garbage-collection';
if ( resource === 'stopped' && this.get('desired') === false ) {
return 'pending-delete';
}
else if ( C.ACTIVEISH_STATES.indexOf(resource) >= 0 )
{

View File

@ -72,7 +72,7 @@ var Host = Resource.extend(StateCounts,{
var out = [
{ label: 'action.edit', icon: 'icon icon-edit', action: 'edit', enabled: !!a.update },
{ label: 'action.clone', icon: 'icon icon-copy', action: 'clone', enabled: !!this.get('driver') }
// { label: 'action.clone', icon: 'icon icon-copy', action: 'clone', enabled: !!this.get('driver') }
];
if ( this.get('links.config') )

View File

@ -41,6 +41,7 @@ var Identity = Resource.extend({
case C.PROJECT.TYPE_GITHUB_USER:
case C.PROJECT.TYPE_LDAP_USER:
case C.PROJECT.TYPE_OPENLDAP_USER:
case C.PROJECT.TYPE_SHIBBOLETH_USER:
return C.PROJECT.PERSON;
case C.PROJECT.TYPE_GITHUB_TEAM:
@ -50,6 +51,7 @@ var Identity = Resource.extend({
case C.PROJECT.TYPE_AZURE_GROUP:
case C.PROJECT.TYPE_LDAP_GROUP:
case C.PROJECT.TYPE_OPENLDAP_GROUP:
case C.PROJECT.TYPE_SHIBBOLETH_GROUP:
return C.PROJECT.ORG;
}
}.property('externalIdType'),
@ -73,11 +75,13 @@ var Identity = Resource.extend({
case C.PROJECT.TYPE_AZURE_USER:
case C.PROJECT.TYPE_LDAP_USER:
case C.PROJECT.TYPE_OPENLDAP_USER:
case C.PROJECT.TYPE_SHIBBOLETH_USER:
key = 'model.identity.displayType.user';
break;
case C.PROJECT.TYPE_AZURE_GROUP:
case C.PROJECT.TYPE_LDAP_GROUP:
case C.PROJECT.TYPE_OPENLDAP_GROUP:
case C.PROJECT.TYPE_SHIBBOLETH_GROUP:
key = 'model.identity.displayType.group';
break;
case C.PROJECT.TYPE_GITHUB_TEAM:

View File

@ -94,6 +94,7 @@ var Service = Resource.extend(StateCounts, {
switch ( this.get('lcType') )
{
case 'service': route = 'scaling-groups.new'; break;
case 'scalinggroup': route = 'scaling-groups.new'; break;
case 'dnsservice': route = 'dns.new'; break;
case 'loadbalancerservice': route = 'balancers.new'; break;
case 'externalservice': route = 'dns.new'; break;

View File

@ -21,6 +21,7 @@
<hr class="mt-40 mb-40"/>
<div class="pb-10">
{{input-files
accept=".yml, .yaml"
changed=(action (mut files))
header='newStack.files.label'
addActionLabel='newStack.files.addActionLabel'

View File

@ -105,9 +105,10 @@ export default Ember.Service.extend({
case 'never':
return false;
case 'default_hide':
return user !== true;
return user === true;
default:
// also 'default_show':
// user can be null so it must be exactly false
return user !== false;
}
},

View File

@ -11,6 +11,16 @@
&.text-success:hover {
color: $success;
}
// Successful states are de-emphasized by using [text-]color instead of background-color
&.bg-muted {
background-color: transparent;
color: $text-muted;
}
&.text-success:hover {
color: $text-muted;
}
}
.grid TD.state {

View File

@ -29,6 +29,7 @@ var C = {
COMMUNITY_KEY: 'community',
COMMUNITY_VALUE: 'https://git.rancher.io/community-catalog.git',
DEFAULT_BRANCH: 'master',
LIBRARY_BRANCH: '${RELEASE}',
},
COOKIE: {
@ -174,6 +175,7 @@ var C = {
LAUNCH_CONFIG: 'io.rancher.service.launch.config',
LAUNCH_CONFIG_PRIMARY: 'io.rancher.service.primary.launch.config',
SIDEKICK: 'io.rancher.sidekicks',
BALANCER_TARGET: 'io.rancher.lb_service.target'
},
LANGUAGE: {

View File

@ -491,7 +491,7 @@ containerPage:
security: Security
portsTab:
header: Ports
detail: 'These properties show what ports have been mapped and where.'
detail: 'Mappings of container listening ports to host ports on public IP addresses'
status: |
{count, plural,
=0 {No Ports}
@ -1080,7 +1080,7 @@ servicePage:
noData: No Links
certsTab:
title: Certificates
detail: 'Certificates added to service.'
detail: 'Certificates used for TLS-termination of requests.'
status: |
{count, plural,
=0 {No certificates}
@ -1104,7 +1104,7 @@ servicePage:
placeholder: e.g. Balancer for mycompany.com
portsTab:
title: Ports
detail: 'These properties show what ports have been mapped and where.'
detail: 'Mappings of container listening ports to host ports on public IP addresses.'
status: |
{count, plural,
=0 {No Ports}
@ -1154,10 +1154,10 @@ signupPage:
form:
button: Register
labels:
loginUsername: Name*
email: Email*
loginUsername: Name
email: Email
cc: Credit Card Info
pw: Password*
pw: Password
emailSuccess:
header: Welcome to Container Cloud
confirm:
@ -1982,7 +1982,7 @@ formCloudHost:
formCommand:
title: Command
detail: These properties control the executable that will be run when the container is started.
detail: Configuration of the executable that will be run when the container is started.
command:
label: Command
placeholder: e.g. /usr/sbin/httpd -f httpd.conf
@ -2092,8 +2092,8 @@ formEngineOpts:
formHealthCheck:
title: Health Check
detail: A health check allows {appName} to know if your container is healthy. For scaling groups, an unhealthy container can be automatically replaced.
detailDns: A health check allows {appName} to know if the external resource is healty or not. This will be used when this record is the target of a Load Balancer.
detail: Periodically make a request to the container to see if it is responding correctly. An unhealthy container will be excluded from Load Balancers. Scaling Groups can automatically replace unhealthy containers with a new one.
detailDns: A health check allows {appName} to know if the external resource is healty or not. An unhealthy target will be exlcluded from Load Balancers.
checkType:
none: None
tcp: Check that a TCP connection opens successfully
@ -2134,12 +2134,6 @@ formHealthCheck:
label: When Unhealthy
none: Take no action
recreate: Re-create
recreateOnQuorumPrefix: Re-create, but only if at least
recreateOnQuorumSuffix: |
{quorum, plural,
=1 {container is}
other {containers are}
} healthy
formKeyValue:
addAction: Add Pair
@ -2402,14 +2396,14 @@ formSslTermination:
prompt: Choose a Certificate...
alternateCertificate:
prompt: Choose a Certificate...
certificate: Certificate*
certificate: Certificate
alternateCerts: Alternate Certs
addAlternate: Add Alternate Certificate
noCertificates: There are no certificates to use.
noAlternateCertificates: There are no other certificates to use.
helpBlock: |
"Note: Some older SSL/TLS clients do not support <a href="https://en.wikipedia.org/wiki/Server_Name_Indication" target="_blank">Server Name Indication (SNI)</a>; these clients will always be offered the main Certificate Modern clients will be offered an appropriate certificate from the Alternate Certificates list if a match is found."
notNeeded: There are no SSL/TLS ports configured.
"Note: Some older SSL/TLS clients do not support <a href="https://en.wikipedia.org/wiki/Server_Name_Indication" target="_blank">Server Name Indication (SNI)</a>; these clients will always be offered the main Certificate. Modern clients will be offered an appropriate certificate from the Alternate Certificates list if a match is found."
notNeeded: There are no SSL/TLS Listening Ports configured with a valid Target Rule.
formStack:
label:
@ -2429,10 +2423,16 @@ formStack:
validation: "Stack: {error}"
formStickiness:
title: Sticky Sessions
detail: Configure the balancer to send requests for a given client to a consistent target container.
title: Target Routing
detail: Configure the balancer to send requests for a given client to a consistent target container or to the same host the balancer is running on..
balancerTarget: Target Container Preference
any: Send requests to a healthy target container on any host.
preferLocal: Prefer containers on the same host as the balancer. (If none are healthy, send to containers on a different host)
onlyLocal: "Use only containers on the same host as the balancer. (If none are healthy, return <code>503</code>)"
sticky: Sticky Sessions
none: None
newCookie: Create new cookie
newCookie: Load Balancer defines a stickiness cookie
cookieName: Cookie Name
mode: Mode
domain: Domain
@ -2440,7 +2440,7 @@ formStickiness:
indirect: Indirect
sendHeader: Send no-cache header
onPost: Only set cookie on POST
noPorts: There are no HTTP Listeners configured.
noPorts: There are no valid Target Rules configured for a HTTP listener.
placeholder:
sticky: e.g. sticky
@ -2737,7 +2737,7 @@ k8s:
labelsSection:
kind: Kind
title: Labels
detail: These properties show what labels exist.
detail: Key/Value data that can be used in Host Scheduling rules or as part of configuring other advanced options.
status: |
{count, plural,
=0 {No labels}

2
vendor/icons vendored

@ -1 +1 @@
Subproject commit 178e091d996fe5dd05b2f9c34b447d36c2b2e165
Subproject commit 6f7e52bf171e253ce70ee19ded57e18af60832ad