{{/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