diff --git a/app/apps-tab/index/template.hbs b/app/apps-tab/index/template.hbs index 69516629e..9fc3ab31a 100644 --- a/app/apps-tab/index/template.hbs +++ b/app/apps-tab/index/template.hbs @@ -14,6 +14,6 @@ expanded=(array-includes expandedStacks stack.id) }} {{else}} -

You should add a catalog item...

+ {{empty-table resource="container" newRoute="catalog-tab" newTranslationKey="nav.apps.launch"}} {{/each}} diff --git a/app/components/container/form-security/component.js b/app/components/container/form-security/component.js index 96c79ba9b..540448ee1 100644 --- a/app/components/container/form-security/component.js +++ b/app/components/container/form-security/component.js @@ -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); } }), diff --git a/app/components/container/new-edit/component.js b/app/components/container/new-edit/component.js index 44875ab6b..82afdfd23 100644 --- a/app/components/container/new-edit/component.js +++ b/app/components/container/new-edit/component.js @@ -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 diff --git a/app/components/edit-balancer/component.js b/app/components/edit-balancer/component.js index 65c772ecb..26509926a 100644 --- a/app/components/edit-balancer/component.js +++ b/app/components/edit-balancer/component.js @@ -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 ) diff --git a/app/components/edit-balancer/template.hbs b/app/components/edit-balancer/template.hbs index 650db3278..b09e1de72 100644 --- a/app/components/edit-balancer/template.hbs +++ b/app/components/edit-balancer/template.hbs @@ -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 diff --git a/app/components/env-catalog/component.js b/app/components/env-catalog/component.js index 9761c2753..d735fdff8 100644 --- a/app/components/env-catalog/component.js +++ b/app/components/env-catalog/component.js @@ -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'); } }); diff --git a/app/components/form-balancer-listeners/component.js b/app/components/form-balancer-listeners/component.js index 911717052..e453263d0 100644 --- a/app/components/form-balancer-listeners/component.js +++ b/app/components/form-balancer-listeners/component.js @@ -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(); }, diff --git a/app/components/form-balancer-listeners/template.hbs b/app/components/form-balancer-listeners/template.hbs index 637155751..f87cafab5 100644 --- a/app/components/form-balancer-listeners/template.hbs +++ b/app/components/form-balancer-listeners/template.hbs @@ -6,13 +6,6 @@ {{t 'formBalancerListeners.addPortLabel'}} - {{#unless showBackend}} -
- -
- {{/unless}}
@@ -63,7 +56,6 @@ protocol=port.protocol rulesChanged=(action 'rulesChanged') singleTarget=false - showBackend=showBackend editing=true }}
diff --git a/app/components/form-balancer-rules/component.js b/app/components/form-balancer-rules/component.js index 3ebc219bb..b84504e20 100644 --- a/app/components/form-balancer-rules/component.js +++ b/app/components/form-balancer-rules/component.js @@ -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() { diff --git a/app/components/form-balancer-rules/template.hbs b/app/components/form-balancer-rules/template.hbs index ca8bd45d7..92de56293 100644 --- a/app/components/form-balancer-rules/template.hbs +++ b/app/components/form-balancer-rules/template.hbs @@ -116,6 +116,13 @@ {{/each}} + {{#unless showBackend}} +
+ +
+ {{/unless}} {{else}} {{t 'formBalancerRules.noRules'}} {{/if}} diff --git a/app/components/form-healthcheck/component.js b/app/components/form-healthcheck/component.js index a7cfdd21b..08a639861 100644 --- a/app/components/form-healthcheck/component.js +++ b/app/components/form-healthcheck/component.js @@ -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 = []; diff --git a/app/components/form-healthcheck/template.hbs b/app/components/form-healthcheck/template.hbs index be56e4c9f..27d577bf7 100644 --- a/app/components/form-healthcheck/template.hbs +++ b/app/components/form-healthcheck/template.hbs @@ -159,16 +159,6 @@
-
- -
{{/input-or-display}} {{/if}} {{/if}} diff --git a/app/components/form-ssl-termination/template.hbs b/app/components/form-ssl-termination/template.hbs index f70d8eff8..6a7852503 100644 --- a/app/components/form-ssl-termination/template.hbs +++ b/app/components/form-ssl-termination/template.hbs @@ -7,76 +7,79 @@ expand=(action expandFn) }} - {{#if allCertificates.length}} -
-
- + {{#liquid-if service.lbConfig.needsCertificate}} + {{#if allCertificates.length}} +
+
+ +
+
+ {{new-select + classNames="form-control" + prompt=(t 'formSslTermination.defaultCertificate.prompt') + content=allCertificates + optionLabelPath="displayDetailedName" + optionValuePath="id" + value=lbConfig.defaultCertificateId + }} +
-
- {{new-select - classNames="form-control" - prompt=(t 'formSslTermination.defaultCertificate.prompt') - content=allCertificates - optionLabelPath="displayDetailedName" - optionValuePath="id" - value=lbConfig.defaultCertificateId - }} -
-
-
-
- -
-
- - - - - - - - - {{#each alternates as |alt|}} +
+
+ +
+
+
- {{#if alternateCertificates.length}} - - {{else}} - {{t 'formSslTermination.noAlternateCertificates'}} - {{/if}} -  
+ - + - {{/each}} - -
- {{new-select - classNames="form-control" - prompt=(t 'formSslTermination.alternateCertificate.prompt') - content=alternateCertificates - optionLabelPath="displayDetailedName" - optionValuePath="id" - value=alt.value - }} - - {{#unless link.existing}} - - {{/unless}} + {{#if alternateCertificates.length}} + + {{else}} + {{t 'formSslTermination.noAlternateCertificates'}} + {{/if}}  
+ + + {{#each alternates as |alt|}} + + + {{new-select + classNames="form-control" + prompt=(t 'formSslTermination.alternateCertificate.prompt') + content=alternateCertificates + optionLabelPath="displayDetailedName" + optionValuePath="id" + value=alt.value + }} + + + {{#unless link.existing}} + + {{/unless}} + + + {{/each}} + + +
-
-
-
-

{{t 'formSslTermination.helpBlock' htmlSafe=true}}

+
+
+

{{t 'formSslTermination.helpBlock' htmlSafe=true}}

+
-
+ {{else}} + {{t 'formSslTermination.noCertificates'}} + {{/if}} {{else}} - {{t 'formSslTermination.noCertificates'}} - {{/if}} - + {{t 'formSslTermination.notNeeded'}} + {{/liquid-if}} {{/accordion-list-item}} diff --git a/app/components/form-stickiness/component.js b/app/components/form-stickiness/component.js index 0c8c34451..1326264a4 100644 --- a/app/components/form-stickiness/component.js +++ b/app/components/form-stickiness/component.js @@ -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; diff --git a/app/components/form-stickiness/template.hbs b/app/components/form-stickiness/template.hbs index cd41b792c..35281cf0e 100644 --- a/app/components/form-stickiness/template.hbs +++ b/app/components/form-stickiness/template.hbs @@ -6,6 +6,21 @@ expandAll=expandAll expand=(action expandFn) }} + + +
+ +
+
+ +
+
+ +
+ +
+ + {{#liquid-if lbConfig.canSticky}}
@@ -62,5 +77,7 @@
{{/liquid-if}} + {{else}} + {{t 'formStickiness.noPorts'}} {{/liquid-if}} {{/accordion-list-item}} diff --git a/app/components/host-pod/template.hbs b/app/components/host-pod/template.hbs index 9f23e47f3..8fe8b8b36 100644 --- a/app/components/host-pod/template.hbs +++ b/app/components/host-pod/template.hbs @@ -78,7 +78,7 @@ {{/each}} {{else}} {{#each groupedInstances as |group|}} - {{#if (or showAdd group.instances.length)}} + {{#if group.instances.length}}
@@ -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}}
{{/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}}
{{/if}} diff --git a/app/components/new-catalog/component.js b/app/components/new-catalog/component.js index 68ced3b68..78b1e9d3e 100644 --- a/app/components/new-catalog/component.js +++ b/app/components/new-catalog/component.js @@ -167,9 +167,8 @@ export default Ember.Component.extend(NewOrEdit, { item.answer = item.default; } }); - return response; } - + return response; }); this.set('selectedTemplateModel', selectedTemplateModel); diff --git a/app/components/settings/catalog-url/component.js b/app/components/settings/catalog-url/component.js index 4d1219230..013aa8467 100644 --- a/app/components/settings/catalog-url/component.js +++ b/app/components/settings/catalog-url/component.js @@ -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]; } diff --git a/app/components/settings/danger-zone/component.js b/app/components/settings/danger-zone/component.js index 7f6727bb3..b6558a843 100644 --- a/app/components/settings/danger-zone/component.js +++ b/app/components/settings/danger-zone/component.js @@ -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({ diff --git a/app/containers/new/route.js b/app/containers/new/route.js index f39b0e9ab..6ee8f35ff 100644 --- a/app/containers/new/route.js +++ b/app/containers/new/route.js @@ -16,7 +16,7 @@ export default Ember.Route.extend({ if ( params.upgrade ) { return Ember.Object.create({ - instance: instance, + instance: results.existing.clone(), }); } diff --git a/app/containers/new/template.hbs b/app/containers/new/template.hbs index ddb481e40..2d7d26130 100644 --- a/app/containers/new/template.hbs +++ b/app/containers/new/template.hbs @@ -1,5 +1,5 @@ {{container/new-edit - isUpgrade=isUpgrade + isUpgrade=upgrade isService=false launchConfig=model.instance primaryResource=model.instance diff --git a/app/mixins/cattle-transitioning-resource.js b/app/mixins/cattle-transitioning-resource.js index e06cd4999..cc3abe84d 100644 --- a/app/mixins/cattle-transitioning-resource.js +++ b/app/mixins/cattle-transitioning-resource.js @@ -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' }, diff --git a/app/mixins/grouped-instances.js b/app/mixins/grouped-instances.js index 1c4a064b8..ff0edb462 100644 --- a/app/mixins/grouped-instances.js +++ b/app/mixins/grouped-instances.js @@ -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]; } diff --git a/app/mixins/state-counts.js b/app/mixins/state-counts.js index cbd9203ef..2643a22b6 100644 --- a/app/mixins/state-counts.js +++ b/app/mixins/state-counts.js @@ -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; diff --git a/app/models/container.js b/app/models/container.js index 377bfac4e..cfd6b9931 100644 --- a/app/models/container.js +++ b/app/models/container.js @@ -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 ) { diff --git a/app/models/host.js b/app/models/host.js index 069aad059..82417bc36 100644 --- a/app/models/host.js +++ b/app/models/host.js @@ -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') ) diff --git a/app/models/identity.js b/app/models/identity.js index e52483b35..a46361398 100644 --- a/app/models/identity.js +++ b/app/models/identity.js @@ -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: diff --git a/app/models/service.js b/app/models/service.js index bcaddb422..67b9f0ca7 100644 --- a/app/models/service.js +++ b/app/models/service.js @@ -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; diff --git a/app/new-stack/template.hbs b/app/new-stack/template.hbs index 1a863e49b..d59d502e3 100644 --- a/app/new-stack/template.hbs +++ b/app/new-stack/template.hbs @@ -21,6 +21,7 @@
{{input-files + accept=".yml, .yaml" changed=(action (mut files)) header='newStack.files.label' addActionLabel='newStack.files.addActionLabel' diff --git a/app/services/prefs.js b/app/services/prefs.js index d5d5a9bcc..b8df0681c 100644 --- a/app/services/prefs.js +++ b/app/services/prefs.js @@ -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; } }, diff --git a/app/styles/components/_badge-state.scss b/app/styles/components/_badge-state.scss index ab7cd7b46..4ded207cc 100644 --- a/app/styles/components/_badge-state.scss +++ b/app/styles/components/_badge-state.scss @@ -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 { diff --git a/app/utils/constants.js b/app/utils/constants.js index e777d96e5..2f135ec79 100644 --- a/app/utils/constants.js +++ b/app/utils/constants.js @@ -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: { diff --git a/translations/en-us.yaml b/translations/en-us.yaml index 27dc1f845..0bb814d9a 100644 --- a/translations/en-us.yaml +++ b/translations/en-us.yaml @@ -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 Server Name Indication (SNI); 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 Server Name Indication (SNI); 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 503)" + + 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} diff --git a/vendor/icons b/vendor/icons index 178e091d9..6f7e52bf1 160000 --- a/vendor/icons +++ b/vendor/icons @@ -1 +1 @@ -Subproject commit 178e091d996fe5dd05b2f9c34b447d36c2b2e165 +Subproject commit 6f7e52bf171e253ce70ee19ded57e18af60832ad