Merge pull request #1484 from vincent99/master

Turn on local auth
This commit is contained in:
Vincent Fiduccia 2017-12-13 16:27:22 -07:00 committed by GitHub
commit ac9307e52e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 319 additions and 354 deletions

View File

@ -14,7 +14,7 @@ export default Controller.extend({
isGithub : equal('access.provider', 'githubconfig'), isGithub : equal('access.provider', 'githubconfig'),
isActiveDirectory : equal('access.provider', 'ldapconfig'), isActiveDirectory : equal('access.provider', 'ldapconfig'),
isOpenLdap : equal('access.provider', 'openldapconfig'), isOpenLdap : equal('access.provider', 'openldapconfig'),
isLocal : equal('access.provider', 'localauthconfig'), isLocal : true, // @TODO-2.0 equal('access.provider', 'localauthconfig'),
isAzureAd : equal('access.provider', 'azureadconfig'), isAzureAd : equal('access.provider', 'azureadconfig'),
isShibboleth : equal('access.provider', 'shibbolethconfig'), isShibboleth : equal('access.provider', 'shibbolethconfig'),
isCaas : computed('app.mode', function() { isCaas : computed('app.mode', function() {

View File

@ -31,7 +31,6 @@
</div> </div>
{{/if}} {{/if}}
{{login-user-pass action="authenticate" waiting=waiting}}
{{#if (or isLocal isActiveDirectory isOpenLdap isAzureAd)}} {{#if (or isLocal isActiveDirectory isOpenLdap isAzureAd)}}
{{login-user-pass action="authenticate" waiting=waiting}} {{login-user-pass action="authenticate" waiting=waiting}}
{{/if}} {{/if}}

View File

@ -16,7 +16,7 @@ export default Service.extend({
// These are set by authenticated/route // These are set by authenticated/route
// Is access control enabled // Is access control enabled
enabled: false, // @TODO-2.0 have auth again someday... null, enabled: true, // @TODO-2.0 remove this, always enabled
// What kind of access control // What kind of access control
provider: null, provider: null,
@ -102,39 +102,50 @@ export default Service.extend({
login(code) { login(code) {
var session = this.get('session'); var session = this.get('session');
return this.get('globalStore').rawRequest({ this.get('cookies').setWithOptions('Authentication', btoa(code), {
url: 'token', path: '/',
method: 'POST', secure: window.location.protocol === 'https:'
data: {
code: code,
authProvider: this.get('provider'),
},
}).then((xhr) => {
var auth = xhr.body;
var interesting = {};
C.TOKEN_TO_SESSION_KEYS.forEach((key) => {
if ( typeof auth[key] !== 'undefined' )
{
interesting[key] = auth[key];
}
});
this.get('cookies').setWithOptions(C.COOKIE.TOKEN, auth['jwt'], {
path: '/',
secure: window.location.protocol === 'https:'
});
session.setProperties(interesting);
return xhr;
}).catch((res) => {
let err;
try {
err = res.body;
} catch(e) {
err = {type: 'error', message: 'Error logging in'};
}
return reject(err);
}); });
// @TODO-2.0
const FALSE = false;
if ( FALSE ) {
return this.get('globalStore').rawRequest({
url: 'token',
method: 'POST',
data: {
code: code,
authProvider: this.get('provider'),
},
}).then((xhr) => {
var auth = xhr.body;
var interesting = {};
C.TOKEN_TO_SESSION_KEYS.forEach((key) => {
if ( typeof auth[key] !== 'undefined' )
{
interesting[key] = auth[key];
}
});
this.get('cookies').setWithOptions(C.COOKIE.TOKEN, auth['jwt'], {
path: '/',
secure: window.location.protocol === 'https:'
});
session.setProperties(interesting);
return xhr;
}).catch((res) => {
let err;
try {
err = res.body;
} catch(e) {
err = {type: 'error', message: 'Error logging in'};
}
return reject(err);
});
} else {
return resolve(true);
}
}, },
clearToken() { clearToken() {

View File

@ -1,92 +1,57 @@
import { next, scheduleOnce } from '@ember/runloop'; import { next } from '@ember/runloop';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
import { get, set, observer } from '@ember/object';
import Component from '@ember/component'; import Component from '@ember/component';
import { parsePortSpec } from 'ui/utils/parse-port';
import layout from './template'; import layout from './template';
const protocolOptions = [ const protocolOptions = [
{label: 'TCP', value: 'tcp'}, {label: 'TCP', value: 'TCP'},
{label: 'UDP', value: 'udp'} {label: 'UDP', value: 'UDP'}
]; ];
export default Component.extend({ export default Component.extend({
layout, layout,
intl: service(), intl: service(),
// The initial ports to show, as an array of objects initialPorts: null,
initialPorts : null, showIp: null,
editing: false,
// Ignore the ID and force each initial port to be considered 'new' (for clone) ports: null,
editing : false,
portsArray : null,
protocolOptions : protocolOptions, protocolOptions : protocolOptions,
showIp : null,
init() { init() {
this._super(...arguments); this._super(...arguments);
var out = []; let ports = get(this, 'initialPorts');
var ports = this.get('initialPorts'); if ( ports ) {
if ( ports ) ports = ports.map((obj) => {
{ const out = obj.cloneForNew()
ports.forEach((value) => { set(out, 'existing', true);
if ( typeof value === 'object' )
{
var pub = '';
var existing = !!value.id;
if ( value.publicPort )
{
pub = value.publicPort+'';
}
if ( value.bindAddress ) if ( get(obj, 'hostIP') ) {
{ set(this, 'showIp', true);
next(() => { this.send('showIp'); });
}
out.push({
existing: existing,
obj: value,
bindAddress: value.bindAddress||null,
public: pub,
private: value.privatePort,
protocol: value.protocol,
});
} }
else if ( typeof value === 'string' )
{
// Strings, from clone/edit
var parsed = parsePortSpec(value,'tcp');
if ( parsed.hostIp ) return out;
{
next(() => { this.send('showIp'); });
}
out.push({
existing: false,
bindAddress: parsed.hostIp,
public: parsed.hostPort,
private: parsed.container,
protocol: parsed.protocol
});
}
else
{
console.error('Unknown port value', value);
}
}); });
} else {
ports = [];
} }
scheduleOnce('afterRender', () => { set(this, 'ports', ports);
this.set('portsArray', out);
this.portsArrayDidChange();
});
}, },
actions: { actions: {
addPort() { addPort() {
this.get('portsArray').pushObject({public: '', private: '', protocol: 'tcp'}); this.get('ports').pushObject(get(this,'store').createRecord({
type: 'containerPort',
containerPort: '',
hostPort: '',
hostIP: '',
protocol: 'TCP'
}));
next(() => { next(() => {
if ( this.isDestroyed || this.isDestroying ) { if ( this.isDestroyed || this.isDestroying ) {
return; return;
@ -97,7 +62,7 @@ export default Component.extend({
}, },
removePort(obj) { removePort(obj) {
this.get('portsArray').removeObject(obj); this.get('ports').removeObject(obj);
}, },
showIp() { showIp() {
@ -105,70 +70,35 @@ export default Component.extend({
}, },
}, },
portsArrayDidChange: function() { portsChanged: observer('ports.@each.{containerPort,hostPort,hostIP,protocol}', function() {
var out = []; const errors = [];
this.get('portsArray').forEach(function(row) { const seen = {};
if ( !row.protocol ) { const intl = get(this, 'intl');
return; const ports = get(this, 'ports');
ports.forEach((obj) => {
let hostIP = obj.hostIP;
let containerPort = obj.containerPort;
let hostPort = obj.hostPort;
let protocol = obj.protocol;
errors.pushObjects(obj.validationErrors());
if ( !containerPort && (hostPort || hostIP) ) {
errors.push(intl.t('formPorts.error.privateRequired'));
} }
let bindAddress = row.bindAddress; if ( hostIP && !hostPort ) {
if ( bindAddress && bindAddress.indexOf(':') > 0 && bindAddress.indexOf('[') !== 0 ) { errors.push(intl.t('formPorts.error.publicRequired'));
// IPv6
bindAddress = '[' + bindAddress + ']';
} }
// If there's a public and no private, the private should be the same as public. if ( hostPort ) {
if ( row.public && !row.private ) const key = '['+ (hostIP||'0.0.0.0') + ']:' + hostPort + '/' + protocol;
{
let str = row.public +':'+ row.public +'/'+ row.protocol;
if ( bindAddress ) {
str = bindAddress +':'+ str;
}
out.push(str);
}
else if ( row.private )
{
let str = '';
if ( row.public )
{
if ( bindAddress ) {
str += bindAddress +':';
}
str += row.public+':';
}
str += row.private +'/'+ row.protocol;
out.push(str);
}
});
this.sendAction('changed', this.get('portsArray'));
this.sendAction('changedStr', out);
}.observes('portsArray.@each.{bindAddress,public,private,protocol}'),
validate: function() {
var errors = [];
let seen = {};
this.get('portsArray').forEach((row) => {
if ( !row.private && (row.public || row.bindAddress)) {
errors.push(this.get('intl').t('formPorts.error.privateRequired'));
}
if ( row.bindAddress && !row.public ) {
errors.push(this.get('intl').t('formPorts.error.publicRequired'));
}
if ( row.public ) {
let key = '['+ (row.bindAddress||'0.0.0.0') + ']:' + row.public + '/' + row.protocol;
if ( seen[key] ) { if ( seen[key] ) {
errors.push(this.get('intl').t('formPorts.error.'+(row.bindAddress ? 'mixedIpPort' : 'mixedPort'), { errors.push(intl.t('formPorts.error.'+(hostIP ? 'mixedIpPort' : 'mixedPort'), {
ip: row.bindAddress, ip: hostIP,
port: row.public, port: hostPort,
proto: row.protocol, proto: protocol
})); }));
} else { } else {
seen[key] = true; seen[key] = true;
@ -177,5 +107,6 @@ export default Component.extend({
}); });
this.set('errors', errors.uniq()); this.set('errors', errors.uniq());
}.observes('portsArray.@each.{bindAddress,public,private,protocol}'), this.sendAction('changed', ports.slice());
}),
}); });

View File

@ -1,6 +1,6 @@
<div class="clearfix {{unless editing 'box'}}"> <div class="clearfix {{unless editing 'box'}}">
<label class="{{if editing 'acc-label'}}">{{t 'formPorts.header'}}</label> <label class="{{if editing 'acc-label'}}">{{t 'formPorts.header'}}</label>
{{#if (and portsArray.length (not showIp))}} {{#if (and ports.length (not showIp))}}
{{#if editing}} {{#if editing}}
<div class="pull-right text-small"> <div class="pull-right text-small">
<a role="button" class="btn bg-transparent p-0" {{action "showIp"}}> <a role="button" class="btn bg-transparent p-0" {{action "showIp"}}>
@ -10,40 +10,40 @@
{{/if}} {{/if}}
{{/if}} {{/if}}
{{#if portsArray.length}} {{#if ports.length}}
<table class="table fixed no-lines small mb-10"> <table class="table fixed no-lines small mb-10">
<thead> <thead>
<tr class="hidden-sm"> <tr class="hidden-sm">
{{#if showIp}} {{#if showIp}}
<th>{{t 'formPorts.bindAddress.label'}}</th> <th>{{t 'formPorts.hostIp.label'}}</th>
<th width="10"></th> <th width="10"></th>
{{/if}} {{/if}}
<th class="{{unless editing 'acc-label'}}">{{t 'formPorts.public.label'}}</th> <th class="{{unless editing 'acc-label'}}">{{t 'formPorts.hostPort.label'}}</th>
<th width="10"></th> <th width="10"></th>
<th class="{{unless editing 'acc-label'}}">{{t 'formPorts.private.label'}}{{#if editing}}{{field-required}}{{/if}}</th> <th class="{{unless editing 'acc-label'}}">{{t 'formPorts.containerPort.label'}}{{#if editing}}{{field-required}}{{/if}}</th>
<th width="10"></th> <th width="10"></th>
<th class="{{unless editing 'acc-label'}}" width="80">{{t 'formPorts.protocol.label'}}</th> <th class="{{unless editing 'acc-label'}}" width="80">{{t 'formPorts.protocol.label'}}</th>
<th width="40">&nbsp;</th> <th width="40">&nbsp;</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{{#each portsArray as |port|}} {{#each ports as |port|}}
<tr> <tr>
{{#if showIp}} {{#if showIp}}
<td data-title="{{t 'formPorts.public.label'}}"> <td data-title="{{t 'formPorts.hostPort.label'}}">
{{#if port.existing}} {{#if port.existing}}
{{#if port.bindAddress}} {{#if port.hostIP}}
{{port.bindAddress}} {{port.hostIP}}
{{else}} {{else}}
<span class="text-muted">{{t 'generic.any'}}</span> <span class="text-muted">{{t 'generic.any'}}</span>
{{/if}} {{/if}}
{{else}} {{else}}
{{#if editing}} {{#if editing}}
{{input class="form-control input-sm" type="text" value=port.bindAddress placeholder=(t 'formPorts.bindAddress.placeholder')}} {{input class="form-control input-sm" type="text" value=port.hostIP placeholder=(t 'formPorts.hostIp.placeholder')}}
{{else}} {{else}}
{{#if port.bindAddress}} {{#if port.hostIP}}
{{port.bindAddress}} {{port.hostIP}}
{{else}} {{else}}
<span class="text-muted">{{t 'generic.na'}}</span> <span class="text-muted">{{t 'generic.na'}}</span>
{{/if}} {{/if}}
@ -54,23 +54,23 @@
<td>&nbsp;</td> <td>&nbsp;</td>
{{/if}} {{/if}}
<td data-title="{{t 'formPorts.public.label'}}"> <td data-title="{{t 'formPorts.hostPort.label'}}">
{{#if editing}} {{#if editing}}
{{input-integer class="form-control input-sm public" min="1" max="65535" value=port.public placeholder=(t 'formPorts.public.placeholder')}} {{input-integer class="form-control input-sm public" min="1" max="65535" value=port.hostPort placeholder=(t 'formPorts.hostPort.placeholder')}}
{{else}} {{else}}
{{port.public}} {{port.hostPort}}
{{/if}} {{/if}}
</td> </td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td data-title="{{t 'formPorts.private.label'}}"> <td data-title="{{t 'formPorts.containerPort.label'}}">
{{#if port.existing}} {{#if port.existing}}
<div class="text-muted">{{port.private}}</div> <div class="text-muted">{{port.containerPort}}</div>
{{else}} {{else}}
{{#if editing}} {{#if editing}}
{{input-integer class="form-control input-sm" min="1" max="65535" value=port.private placeholder=(t 'formPorts.private.placeholder')}} {{input-integer class="form-control input-sm" min="1" max="65535" value=port.containerPort placeholder=(t 'formPorts.containerPort.placeholder')}}
{{else}} {{else}}
{{port.private}} {{port.containerPort}}
{{/if}} {{/if}}
{{/if}} {{/if}}
</td> </td>

View File

@ -56,10 +56,10 @@
<div class="row"> <div class="row">
<div class="col span-11-of-23 mt-0 mb-0"> <div class="col span-11-of-23 mt-0 mb-0">
{{container/form-ports {{container/form-ports
initialPorts=launchConfig.ports initialPorts=launchConfig.ports
errors=portErrors changed=(action (mut launchConfig.ports))
changedStr=(action (mut launchConfig.ports)) errors=portErrors
editing=true editing=true
}} }}
</div> </div>
<div class="col span-11-of-23 mt-0 mb-0 offset-1-of-23"> <div class="col span-11-of-23 mt-0 mb-0 offset-1-of-23">

View File

@ -6,151 +6,150 @@
expandAll=expandAll expandAll=expandAll
expand=(action expandFn) expand=(action expandFn)
}} }}
{{#if scope.current.isWindows}} {{#if editing}}
<div class="text-center p-20">Healthcheck support is not currently available for Windows.</div> <div class="radio input">
<label>{{radio-button selection=checkType value="none"}} {{t 'formHealthCheck.checkType.none'}}</label>
</div>
<div class="radio input">
<label>{{radio-button selection=checkType value="tcp"}} {{t 'formHealthCheck.checkType.tcp'}}</label>
</div>
<div class="radio input">
<label>{{radio-button selection=checkType value="http"}} {{t 'formHealthCheck.checkType.http'}}</label>
</div>
<div class="radio input">
<label>{{radio-button selection=checkType value="command"}} {{t 'formHealthCheck.checkType.http'}}</label>
</div>
{{else}} {{else}}
{{#if editing}} {{#if checkType}}
<div class="radio input"> <div>
<label>{{radio-button selection=checkType value="none"}} {{t 'formHealthCheck.checkType.none'}}</label> <label class="acc-label">{{t 'generic.type'}}:</label>
</div> {{checkType}}
<div class="radio input">
<label>{{radio-button selection=checkType value="tcp"}} {{t 'formHealthCheck.checkType.tcp'}}</label>
</div>
<div class="radio input">
<label>{{radio-button selection=checkType value="http"}} {{t 'formHealthCheck.checkType.http'}}</label>
</div> </div>
{{else}} {{else}}
{{#if checkType}} <div>{{t 'generic.none'}}</div>
<div>
<label class="acc-label">{{t 'generic.type'}}:</label>
{{checkType}}
</div>
{{else}}
<div>{{t 'generic.none'}}</div>
{{/if}}
{{/if}} {{/if}}
{{/if}}
{{#if (eq checkType "http")}} {{#if (eq checkType "http")}}
<div class="row"> <div class="row">
<div class="col {{if showUriHost 'span-6' 'span-12'}}"> <div class="col {{if showUriHost 'span-6' 'span-12'}}">
<label class="acc-label">{{t 'formHealthCheck.request.label'}}{{field-required}}</label> <label class="acc-label">{{t 'formHealthCheck.request.label'}}{{field-required}}</label>
{{#input-or-display editable=editing value=healthCheck.requestLine}} {{#input-or-display editable=editing value=healthCheck.requestLine}}
<div class="input-group"> <div class="input-group">
<div class="input-group-btn bg-default "> <div class="input-group-btn bg-default ">
<button type="button" class="btn bg-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">{{uriMethod}} <i class="icon icon-chevron-down"></i></button> <button type="button" class="btn bg-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">{{uriMethod}} <i class="icon icon-chevron-down"></i></button>
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
<li role="presentation" class="dropdown-header"> <li role="presentation" class="dropdown-header">
{{t 'formHealthCheck.method.prompt'}} {{t 'formHealthCheck.method.prompt'}}
</li>
{{#each uriMethodChoices as |choice|}}
<li {{action "chooseUriMethod" choice}}>
<a href="#">{{choice}}</a>
</li> </li>
{{#each uriMethodChoices as |choice|}} {{/each}}
<li {{action "chooseUriMethod" choice}}> </ul>
<a href="#">{{choice}}</a>
</li>
{{/each}}
</ul>
</div>
{{input type="text" classNames="form-control" placeholder=(t 'formHealthCheck.path.placeholder') value=uriPath}}
<div class="input-group-btn bg-default">
<button type="button" class="btn bg-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">{{uriVersion}} <i class="icon icon-chevron-down"></i></button>
<ul class="dropdown-menu" role="menu">
<li role="presentation" class="dropdown-header">
{{t 'formHealthCheck.version.prompt'}}
</li>
{{#each uriVersionChoices as |choice|}}
<li {{action "chooseUriVersion" choice}}>
<a href="#">{{choice}}</a>
</li>
{{/each}}
</ul>
</div>
</div> </div>
{{/input-or-display}}
</div> {{input type="text" classNames="form-control" placeholder=(t 'formHealthCheck.path.placeholder') value=uriPath}}
{{#if showUriHost}}
<div class="col span-6"> <div class="input-group-btn bg-default">
<label class="acc-label">{{t 'formHealthCheck.host.label'}}</label> <button type="button" class="btn bg-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">{{uriVersion}} <i class="icon icon-chevron-down"></i></button>
{{#input-or-display editable=editing value=uriHost}} <ul class="dropdown-menu" role="menu">
{{input type="text" classNames="form-control" placeholder=(t 'formHealthCheck.host.placeholder') value=uriHost}} <li role="presentation" class="dropdown-header">
{{/input-or-display}} {{t 'formHealthCheck.version.prompt'}}
</div> </li>
{{/if}} {{#each uriVersionChoices as |choice|}}
<li {{action "chooseUriVersion" choice}}>
<a href="#">{{choice}}</a>
</li>
{{/each}}
</ul>
</div>
</div>
{{/input-or-display}}
</div> </div>
{{/if}} {{#if showUriHost}}
<div class="col span-6">
{{#if (not-eq checkType "none")}} <label class="acc-label">{{t 'formHealthCheck.host.label'}}</label>
<div class="row"> {{#input-or-display editable=editing value=uriHost}}
<div class="col span-4 box"> {{input type="text" classNames="form-control" placeholder=(t 'formHealthCheck.host.placeholder') value=uriHost}}
<label class="acc-label">{{t 'formHealthCheck.port.label'}}{{field-required}}</label>
{{#input-or-display editable=editing value=healthCheck.port}}
{{input-integer min="1" max="65535" classNames="form-control" placeholder=(t 'formHealthCheck.port.placeholder') value=healthCheck.port}}
{{/input-or-display}} {{/input-or-display}}
</div> </div>
{{/if}}
</div>
{{/if}}
<div class="col span-4 box"> {{#if (not-eq checkType "none")}}
<label class="acc-label">{{t 'formHealthCheck.interval.label'}}</label> <div class="row">
{{#input-or-display editable=editing value=healthCheck.interval}} <div class="col span-4 box">
<div class="input-group"> <label class="acc-label">{{t 'formHealthCheck.port.label'}}{{field-required}}</label>
{{input-integer min=1 step=1000 classNames="form-control" value=healthCheck.interval}} {{#input-or-display editable=editing value=healthCheck.port}}
<span class="input-group-addon bg-default">{{t 'formHealthCheck.interval.unit'}}</span> {{input-integer min="1" max="65535" classNames="form-control" placeholder=(t 'formHealthCheck.port.placeholder') value=healthCheck.port}}
</div> {{/input-or-display}}
{{/input-or-display}}
</div>
<div class="col span-4 box">
<label class="acc-label">{{t 'formHealthCheck.timeout.label'}}</label>
{{#input-or-display editable=editing value=healthCheck.responseTimeout}}
<div class="input-group">
{{input-integer min=1 step=100 classNames="form-control" value=healthCheck.responseTimeout}}
<span class="input-group-addon bg-default">{{t 'formHealthCheck.timeout.unit'}}</span>
</div>
{{/input-or-display}}
</div>
</div> </div>
<div class="row"> <div class="col span-4 box">
<div class="col box span-4"> <label class="acc-label">{{t 'formHealthCheck.interval.label'}}</label>
<label class="acc-label">{{t 'formHealthCheck.initializingTimeout.label'}}</label> {{#input-or-display editable=editing value=healthCheck.interval}}
{{#input-or-display editable=editing value=healthCheck.initializingTimeout}} <div class="input-group">
<div class="input-group"> {{input-integer min=1 step=1000 classNames="form-control" value=healthCheck.interval}}
{{input-integer step=100 classNames="form-control" value=healthCheck.initializingTimeout}} <span class="input-group-addon bg-default">{{t 'generic.seconds'}}</span>
<span class="input-group-addon bg-default">{{t 'formHealthCheck.initializingTimeout.unit'}}</span>
</div>
{{/input-or-display}}
</div>
<div class="col box span-4">
<label class="acc-label">{{t 'formHealthCheck.healthyThreshold.label'}}</label>
{{#input-or-display editable=editing value=healthCheck.healthyThreshold}}
<div class="input-group">
{{input-integer min=1 step=1 classNames="form-control" value=healthCheck.healthyThreshold}}
<span class="input-group-addon bg-default">{{t 'formHealthCheck.healthyThreshold.unit'}}</span>
</div>
{{/input-or-display}}
</div>
<div class="col box span-4">
<label class="acc-label">{{t 'formHealthCheck.unhealthyThreshold.label'}}</label>
{{#input-or-display editable=editing value=healthCheck.unhealthyThreshold}}
<div class="input-group">
{{input-integer min=1 step=1 classNames="form-control" value=healthCheck.unhealthyThreshold}}
<span class="input-group-addon bg-default">{{t 'formHealthCheck.unhealthyThreshold.unit'}}</span>
</div>
{{/input-or-display}}
</div>
</div>
{{#if (and isService showStrategy)}}
<label class="acc-label mt-20">{{t 'formHealthCheck.strategy.label'}}</label>
{{#input-or-display editable=editing value=strategy}}
<div class="radio">
<label>{{radio-button selection=strategy value="none"}} {{t 'formHealthCheck.strategy.none'}}</label>
</div>
<div class="radio">
<label>{{radio-button selection=strategy value="recreate"}} {{t 'formHealthCheck.strategy.recreate'}}</label>
</div> </div>
{{/input-or-display}} {{/input-or-display}}
{{/if}} </div>
<div class="col span-4 box">
<label class="acc-label">{{t 'formHealthCheck.timeout.label'}}</label>
{{#input-or-display editable=editing value=healthCheck.responseTimeout}}
<div class="input-group">
{{input-integer min=1 step=100 classNames="form-control" value=healthCheck.responseTimeout}}
<span class="input-group-addon bg-default">{{t 'generic.seconds'}}</span>
</div>
{{/input-or-display}}
</div>
</div>
<div class="row">
<div class="col box span-4">
<label class="acc-label">{{t 'formHealthCheck.initialDelaySeconds.label'}}</label>
{{#input-or-display editable=editing value=healthCheck.initialDelaySeconds}}
<div class="input-group">
{{input-integer step=100 classNames="form-control" value=healthCheck.initialDelaySeconds}}
<span class="input-group-addon bg-default">{{t 'generic.seconds'}}</span>
</div>
{{/input-or-display}}
</div>
<div class="col box span-4">
<label class="acc-label">{{t 'formHealthCheck.successThreshold.label'}}</label>
{{#input-or-display editable=editing value=healthCheck.successThreshold}}
<div class="input-group">
{{input-integer min=1 step=1 classNames="form-control" value=healthCheck.successThreshold}}
<span class="input-group-addon bg-default">{{t 'formHealthCheck.successThreshold.unit'}}</span>
</div>
{{/input-or-display}}
</div>
<div class="col box span-4">
<label class="acc-label">{{t 'formHealthCheck.failureTheshold.label'}}</label>
{{#input-or-display editable=editing value=healthCheck.failureTheshold}}
<div class="input-group">
{{input-integer min=1 step=1 classNames="form-control" value=healthCheck.failureTheshold}}
<span class="input-group-addon bg-default">{{t 'formHealthCheck.failureTheshold.unit'}}</span>
</div>
{{/input-or-display}}
</div>
</div>
{{#if (and isService showStrategy)}}
<label class="acc-label mt-20">{{t 'formHealthCheck.strategy.label'}}</label>
{{#input-or-display editable=editing value=strategy}}
<div class="radio">
<label>{{radio-button selection=strategy value="none"}} {{t 'formHealthCheck.strategy.none'}}</label>
</div>
<div class="radio">
<label>{{radio-button selection=strategy value="recreate"}} {{t 'formHealthCheck.strategy.recreate'}}</label>
</div>
{{/input-or-display}}
{{/if}} {{/if}}
{{/if}} {{/if}}
{{/accordion-list-item}} {{/accordion-list-item}}

View File

@ -87,30 +87,39 @@ export default Mixin.create({
return; return;
} }
let store = this.get('store'); const projectStore = this.get('store');
const clusterStore = this.get('clusterStore');
const globalStore = this.get('globalStore');
let count = 0; let count = 0;
let event = queue.dequeue(); let event = queue.dequeue();
let projectId, clusterId, type;
Ember.beginPropertyChanges(); Ember.beginPropertyChanges();
while ( event ) { while ( event ) {
let resource; if ( !event.data ) {
if ( event.data ) { continue;
resource = store._typeify(event.data);
} }
if ( resource ) { projectId = get(event.data, 'projectId');
let type = get(resource,'type'); clusterId = get(event.data, 'clusterId');
let key = type+'Changed'; type = get(event.data, 'type');
// Fire [thing]Changed() method if present // console.log('Change', type +':'+ event.data.id, clusterId, projectId);
if ( this[key] ) {
this[key](event);
}
// Remove from store if the resource is removed if ( projectId && projectStore.hasType(type) ) {
if ( C.REMOVEDISH_STATES.includes(resource.state) ) { // console.log(' Update project store', type, event.data.id, projectId);
store._remove(type, resource); updateStore(projectStore, event.data);
} }
if ( clusterId && clusterStore.hasType(type) ) {
// console.log(' Update cluster store', type, event.data.id, clusterId);
updateStore(clusterStore, event.data);
}
if ( globalStore.hasType(type) ) {
// console.log(' Update global store', type, event.data.id);
updateStore(globalStore, event.data);
} }
count++; count++;
@ -118,6 +127,26 @@ export default Mixin.create({
} }
Ember.endPropertyChanges(); Ember.endPropertyChanges();
console.log('Processed',count,'change events'); console.log('Processed',count,'change events');
function updateStore(store, data) {
const resource = store._typeify(data);
if ( resource ) {
// Not used by anything anymore
//let type = get(resource,'type');
//let key = type+'Changed';
//
//// Fire [thing]Changed() method if present
//if ( this[key] ) {
// this[key](event);
//}
// Remove from store if the resource is removed
if ( C.REMOVEDISH_STATES.includes(resource.state) ) {
const type = get(resource,'type');
store._remove(type, resource);
}
}
}
}, },
connectSubscribe() { connectSubscribe() {

View File

@ -151,7 +151,8 @@ export default Service.extend(Evented, {
if ( this.get('access.enabled') ) if ( this.get('access.enabled') )
{ {
str += `|Access|\`${this.get('access.provider').replace(/config/,'')}\` ${this.get('access.admin') ? '\`admin\`' : ''}|\n`; let provider = (this.get('access.provider')||'').replace(/config/,'');
str += `|Access|\`${provider}\` ${this.get('access.admin') ? '\`admin\`' : ''}|\n`;
} }
else else
{ {

View File

@ -27,8 +27,8 @@ var C = {
COMMUNITY_KEY: 'community', COMMUNITY_KEY: 'community',
COMMUNITY_VALUE: 'https://git.rancher.io/community-catalog.git', COMMUNITY_VALUE: 'https://git.rancher.io/community-catalog.git',
DEFAULT_BRANCH: 'master', DEFAULT_BRANCH: 'master',
LIBRARY_BRANCH: '${RELEASE}', LIBRARY_BRANCH: '2.0-development', // @TODO-2.0 '${RELEASE}',
COMMUNITY_BRANCH: '${RELEASE}', COMMUNITY_BRANCH: '2.0-development', // @TODO-2.0 '${RELEASE}',
}, },
COOKIE: { COOKIE: {

View File

@ -2010,42 +2010,37 @@ formHealthCheck:
none: None none: None
tcp: Check that a TCP connection opens successfully tcp: Check that a TCP connection opens successfully
http: Check that a HTTP request responds with a successful status code (2xx or 3xx) http: Check that a HTTP request responds with a successful status code (2xx or 3xx)
request: https: Check that a HTTPS request responds with a successful status code
command: Check that a command run inside the container exits successfully (exit code 0)
command:
label: Command
placeholder: e.g. cat /tmp/health
http:
label: HTTP Request label: HTTP Request
method: path:
prompt: "Select a HTTP Method:" placeholder: Request Path e.g. /healthcheck
path: headers:
placeholder: Request Path e.g. /healthcheck label: Host Header
version:
prompt: "Select a HTTP Version:"
host:
label: Host Header
placeholder: e.g. www.example.com
port: port:
label: Listening Port label: Target Container Port
placeholder: e.g. 80 placeholder: e.g. 80
initializingTimeout: initialDelaySeconds:
label: Initializing Timeout label: Delay before initial check
unit: ms unit: ms
reinitializingTimeout: reinitializingTimeout:
label: Reinitializing Timeout label: Reinitializing Timeout
unit: ms unit: ms
interval: periodSeconds:
label: Check Interval label: Check Interval
unit: ms timeoutSeconds:
timeout:
label: Check Timeout label: Check Timeout
unit: ms unit: ms
healthyThreshold: successThreshold:
label: Healthy After label: Healthy After
unit: successes unit: successes
unhealthyThreshold: failureTheshold:
label: Unhealthy After label: Unhealthy After
unit: failures unit: failures
strategy:
label: When Unhealthy
none: Take no action
recreate: Delete container and schedule a replacement
formKeyValue: formKeyValue:
addAction: Add Pair addAction: Add Pair
@ -2141,13 +2136,13 @@ formNetwork:
formPorts: formPorts:
header: Port Mapping header: Port Mapping
addAction: Add Port addAction: Add Port
bindAddress: hostIp:
label: Host IP label: Host IP
placeholder: "Default: All" placeholder: "Default: All"
public: hostPort:
label: Host Port label: Host Port
placeholder: "e.g. 80" placeholder: "e.g. 80"
private: containerPort:
label: Container Port label: Container Port
placeholder: "e.g. 8080" placeholder: "e.g. 8080"
protocol: protocol: