diff --git a/lib/login/addon/controllers/login.js b/lib/login/addon/controllers/login.js index e89f239a6..2e4ae865f 100644 --- a/lib/login/addon/controllers/login.js +++ b/lib/login/addon/controllers/login.js @@ -14,7 +14,7 @@ export default Controller.extend({ isGithub : equal('access.provider', 'githubconfig'), isActiveDirectory : equal('access.provider', 'ldapconfig'), isOpenLdap : equal('access.provider', 'openldapconfig'), - isLocal : equal('access.provider', 'localauthconfig'), + isLocal : true, // @TODO-2.0 equal('access.provider', 'localauthconfig'), isAzureAd : equal('access.provider', 'azureadconfig'), isShibboleth : equal('access.provider', 'shibbolethconfig'), isCaas : computed('app.mode', function() { diff --git a/lib/login/addon/templates/login.hbs b/lib/login/addon/templates/login.hbs index a0cb31ede..d52ad5786 100644 --- a/lib/login/addon/templates/login.hbs +++ b/lib/login/addon/templates/login.hbs @@ -31,7 +31,6 @@ {{/if}} - {{login-user-pass action="authenticate" waiting=waiting}} {{#if (or isLocal isActiveDirectory isOpenLdap isAzureAd)}} {{login-user-pass action="authenticate" waiting=waiting}} {{/if}} diff --git a/lib/shared/addon/access/service.js b/lib/shared/addon/access/service.js index a0bd6c98b..246d2f3ca 100644 --- a/lib/shared/addon/access/service.js +++ b/lib/shared/addon/access/service.js @@ -16,7 +16,7 @@ export default Service.extend({ // These are set by authenticated/route // 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 provider: null, @@ -102,39 +102,50 @@ export default Service.extend({ login(code) { var session = this.get('session'); - 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); + this.get('cookies').setWithOptions('Authentication', btoa(code), { + path: '/', + secure: window.location.protocol === 'https:' }); + + // @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() { diff --git a/lib/shared/addon/components/container/form-ports/component.js b/lib/shared/addon/components/container/form-ports/component.js index 025597a32..dee4f6bbb 100644 --- a/lib/shared/addon/components/container/form-ports/component.js +++ b/lib/shared/addon/components/container/form-ports/component.js @@ -1,92 +1,57 @@ -import { next, scheduleOnce } from '@ember/runloop'; +import { next } from '@ember/runloop'; import { inject as service } from '@ember/service'; +import { get, set, observer } from '@ember/object'; import Component from '@ember/component'; -import { parsePortSpec } from 'ui/utils/parse-port'; import layout from './template'; const protocolOptions = [ - {label: 'TCP', value: 'tcp'}, - {label: 'UDP', value: 'udp'} + {label: 'TCP', value: 'TCP'}, + {label: 'UDP', value: 'UDP'} ]; export default Component.extend({ layout, 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) - editing : false, - portsArray : null, + ports: null, protocolOptions : protocolOptions, - showIp : null, init() { this._super(...arguments); - var out = []; - var ports = this.get('initialPorts'); - if ( ports ) - { - ports.forEach((value) => { - if ( typeof value === 'object' ) - { - var pub = ''; - var existing = !!value.id; - if ( value.publicPort ) - { - pub = value.publicPort+''; - } + let ports = get(this, 'initialPorts'); + if ( ports ) { + ports = ports.map((obj) => { + const out = obj.cloneForNew() + set(out, 'existing', true); - if ( value.bindAddress ) - { - next(() => { this.send('showIp'); }); - } - - out.push({ - existing: existing, - obj: value, - bindAddress: value.bindAddress||null, - public: pub, - private: value.privatePort, - protocol: value.protocol, - }); + if ( get(obj, 'hostIP') ) { + set(this, 'showIp', true); } - else if ( typeof value === 'string' ) - { - // Strings, from clone/edit - var parsed = parsePortSpec(value,'tcp'); - if ( parsed.hostIp ) - { - 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); - } + return out; }); + } else { + ports = []; } - scheduleOnce('afterRender', () => { - this.set('portsArray', out); - this.portsArrayDidChange(); - }); + set(this, 'ports', ports); }, actions: { 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(() => { if ( this.isDestroyed || this.isDestroying ) { return; @@ -97,7 +62,7 @@ export default Component.extend({ }, removePort(obj) { - this.get('portsArray').removeObject(obj); + this.get('ports').removeObject(obj); }, showIp() { @@ -105,70 +70,35 @@ export default Component.extend({ }, }, - portsArrayDidChange: function() { - var out = []; - this.get('portsArray').forEach(function(row) { - if ( !row.protocol ) { - return; + portsChanged: observer('ports.@each.{containerPort,hostPort,hostIP,protocol}', function() { + const errors = []; + const seen = {}; + const intl = get(this, 'intl'); + 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 ( bindAddress && bindAddress.indexOf(':') > 0 && bindAddress.indexOf('[') !== 0 ) { - // IPv6 - bindAddress = '[' + bindAddress + ']'; + if ( hostIP && !hostPort ) { + errors.push(intl.t('formPorts.error.publicRequired')); } - // If there's a public and no private, the private should be the same as public. - if ( row.public && !row.private ) - { - 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 ( hostPort ) { + const key = '['+ (hostIP||'0.0.0.0') + ']:' + hostPort + '/' + protocol; if ( seen[key] ) { - errors.push(this.get('intl').t('formPorts.error.'+(row.bindAddress ? 'mixedIpPort' : 'mixedPort'), { - ip: row.bindAddress, - port: row.public, - proto: row.protocol, + errors.push(intl.t('formPorts.error.'+(hostIP ? 'mixedIpPort' : 'mixedPort'), { + ip: hostIP, + port: hostPort, + proto: protocol })); } else { seen[key] = true; @@ -177,5 +107,6 @@ export default Component.extend({ }); this.set('errors', errors.uniq()); - }.observes('portsArray.@each.{bindAddress,public,private,protocol}'), + this.sendAction('changed', ports.slice()); + }), }); diff --git a/lib/shared/addon/components/container/form-ports/template.hbs b/lib/shared/addon/components/container/form-ports/template.hbs index 71fb2f53a..d724c98ac 100644 --- a/lib/shared/addon/components/container/form-ports/template.hbs +++ b/lib/shared/addon/components/container/form-ports/template.hbs @@ -1,6 +1,6 @@
- {{#if (and portsArray.length (not showIp))}} + {{#if (and ports.length (not showIp))}} {{#if editing}}
@@ -10,40 +10,40 @@ {{/if}} {{/if}} - {{#if portsArray.length}} + {{#if ports.length}} {{#if showIp}} - + {{/if}} - + - + - {{#each portsArray as |port|}} + {{#each ports as |port|}} {{#if showIp}} - {{/if}} - - diff --git a/lib/shared/addon/components/container/new-edit/template.hbs b/lib/shared/addon/components/container/new-edit/template.hbs index b50932e06..4886faa29 100644 --- a/lib/shared/addon/components/container/new-edit/template.hbs +++ b/lib/shared/addon/components/container/new-edit/template.hbs @@ -56,10 +56,10 @@
{{container/form-ports - initialPorts=launchConfig.ports - errors=portErrors - changedStr=(action (mut launchConfig.ports)) - editing=true + initialPorts=launchConfig.ports + changed=(action (mut launchConfig.ports)) + errors=portErrors + editing=true }}
diff --git a/lib/shared/addon/components/form-healthcheck/template.hbs b/lib/shared/addon/components/form-healthcheck/template.hbs index eb5ef6f02..bc9a6e966 100644 --- a/lib/shared/addon/components/form-healthcheck/template.hbs +++ b/lib/shared/addon/components/form-healthcheck/template.hbs @@ -6,151 +6,150 @@ expandAll=expandAll expand=(action expandFn) }} - {{#if scope.current.isWindows}} -
Healthcheck support is not currently available for Windows.
+ {{#if editing}} +
+ +
+
+ +
+
+ +
+
+ +
{{else}} - {{#if editing}} -
- -
-
- -
-
- + {{#if checkType}} +
+ + {{checkType}}
{{else}} - {{#if checkType}} -
- - {{checkType}} -
- {{else}} -
{{t 'generic.none'}}
- {{/if}} +
{{t 'generic.none'}}
{{/if}} + {{/if}} - {{#if (eq checkType "http")}} -
-
- - {{#input-or-display editable=editing value=healthCheck.requestLine}} -
-
- -
- {{/input-or-display}} -
- {{#if showUriHost}} -
- - {{#input-or-display editable=editing value=uriHost}} - {{input type="text" classNames="form-control" placeholder=(t 'formHealthCheck.host.placeholder') value=uriHost}} - {{/input-or-display}} -
- {{/if}} + + {{input type="text" classNames="form-control" placeholder=(t 'formHealthCheck.path.placeholder') value=uriPath}} + +
+ + +
+
+ {{/input-or-display}}
- {{/if}} - - {{#if (not-eq checkType "none")}} -
-
- - {{#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}} + {{#if showUriHost}} +
+ + {{#input-or-display editable=editing value=uriHost}} + {{input type="text" classNames="form-control" placeholder=(t 'formHealthCheck.host.placeholder') value=uriHost}} {{/input-or-display}}
+ {{/if}} +
+ {{/if}} -
- - {{#input-or-display editable=editing value=healthCheck.interval}} -
- {{input-integer min=1 step=1000 classNames="form-control" value=healthCheck.interval}} - {{t 'formHealthCheck.interval.unit'}} -
- {{/input-or-display}} -
- - -
- - {{#input-or-display editable=editing value=healthCheck.responseTimeout}} -
- {{input-integer min=1 step=100 classNames="form-control" value=healthCheck.responseTimeout}} - {{t 'formHealthCheck.timeout.unit'}} -
- {{/input-or-display}} -
+ {{#if (not-eq checkType "none")}} +
+
+ + {{#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 editable=editing value=healthCheck.initializingTimeout}} -
- {{input-integer step=100 classNames="form-control" value=healthCheck.initializingTimeout}} - {{t 'formHealthCheck.initializingTimeout.unit'}} -
- {{/input-or-display}} -
-
- - {{#input-or-display editable=editing value=healthCheck.healthyThreshold}} -
- {{input-integer min=1 step=1 classNames="form-control" value=healthCheck.healthyThreshold}} - {{t 'formHealthCheck.healthyThreshold.unit'}} -
- {{/input-or-display}} -
-
- - {{#input-or-display editable=editing value=healthCheck.unhealthyThreshold}} -
- {{input-integer min=1 step=1 classNames="form-control" value=healthCheck.unhealthyThreshold}} - {{t 'formHealthCheck.unhealthyThreshold.unit'}} -
- {{/input-or-display}} -
-
- - {{#if (and isService showStrategy)}} - - {{#input-or-display editable=editing value=strategy}} -
- -
-
- +
+ + {{#input-or-display editable=editing value=healthCheck.interval}} +
+ {{input-integer min=1 step=1000 classNames="form-control" value=healthCheck.interval}} + {{t 'generic.seconds'}}
{{/input-or-display}} - {{/if}} +
+ + +
+ + {{#input-or-display editable=editing value=healthCheck.responseTimeout}} +
+ {{input-integer min=1 step=100 classNames="form-control" value=healthCheck.responseTimeout}} + {{t 'generic.seconds'}} +
+ {{/input-or-display}} +
+
+ +
+
+ + {{#input-or-display editable=editing value=healthCheck.initialDelaySeconds}} +
+ {{input-integer step=100 classNames="form-control" value=healthCheck.initialDelaySeconds}} + {{t 'generic.seconds'}} +
+ {{/input-or-display}} +
+
+ + {{#input-or-display editable=editing value=healthCheck.successThreshold}} +
+ {{input-integer min=1 step=1 classNames="form-control" value=healthCheck.successThreshold}} + {{t 'formHealthCheck.successThreshold.unit'}} +
+ {{/input-or-display}} +
+
+ + {{#input-or-display editable=editing value=healthCheck.failureTheshold}} +
+ {{input-integer min=1 step=1 classNames="form-control" value=healthCheck.failureTheshold}} + {{t 'formHealthCheck.failureTheshold.unit'}} +
+ {{/input-or-display}} +
+
+ + {{#if (and isService showStrategy)}} + + {{#input-or-display editable=editing value=strategy}} +
+ +
+
+ +
+ {{/input-or-display}} {{/if}} {{/if}} {{/accordion-list-item}} diff --git a/lib/shared/addon/mixins/subscribe.js b/lib/shared/addon/mixins/subscribe.js index 43ebf3e73..b8c97a17e 100644 --- a/lib/shared/addon/mixins/subscribe.js +++ b/lib/shared/addon/mixins/subscribe.js @@ -87,30 +87,39 @@ export default Mixin.create({ 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 event = queue.dequeue(); + let projectId, clusterId, type; Ember.beginPropertyChanges(); while ( event ) { - let resource; - if ( event.data ) { - resource = store._typeify(event.data); + if ( !event.data ) { + continue; } - if ( resource ) { - let type = get(resource,'type'); - let key = type+'Changed'; + projectId = get(event.data, 'projectId'); + clusterId = get(event.data, 'clusterId'); + type = get(event.data, 'type'); - // Fire [thing]Changed() method if present - if ( this[key] ) { - this[key](event); - } +// console.log('Change', type +':'+ event.data.id, clusterId, projectId); - // Remove from store if the resource is removed - if ( C.REMOVEDISH_STATES.includes(resource.state) ) { - store._remove(type, resource); - } + if ( projectId && projectStore.hasType(type) ) { +// console.log(' Update project store', type, event.data.id, projectId); + 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++; @@ -118,6 +127,26 @@ export default Mixin.create({ } Ember.endPropertyChanges(); 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() { diff --git a/lib/shared/addon/settings/service.js b/lib/shared/addon/settings/service.js index 4ce54523b..5ceb69209 100644 --- a/lib/shared/addon/settings/service.js +++ b/lib/shared/addon/settings/service.js @@ -151,7 +151,8 @@ export default Service.extend(Evented, { 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 { diff --git a/lib/shared/addon/utils/constants.js b/lib/shared/addon/utils/constants.js index 4a631e28d..110f1fa40 100644 --- a/lib/shared/addon/utils/constants.js +++ b/lib/shared/addon/utils/constants.js @@ -27,8 +27,8 @@ var C = { COMMUNITY_KEY: 'community', COMMUNITY_VALUE: 'https://git.rancher.io/community-catalog.git', DEFAULT_BRANCH: 'master', - LIBRARY_BRANCH: '${RELEASE}', - COMMUNITY_BRANCH: '${RELEASE}', + LIBRARY_BRANCH: '2.0-development', // @TODO-2.0 '${RELEASE}', + COMMUNITY_BRANCH: '2.0-development', // @TODO-2.0 '${RELEASE}', }, COOKIE: { diff --git a/translations/en-us.yaml b/translations/en-us.yaml index b68d116df..92f9f46d9 100644 --- a/translations/en-us.yaml +++ b/translations/en-us.yaml @@ -2010,42 +2010,37 @@ formHealthCheck: none: None tcp: Check that a TCP connection opens successfully 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 - method: - prompt: "Select a HTTP Method:" - path: - placeholder: Request Path e.g. /healthcheck - version: - prompt: "Select a HTTP Version:" - host: - label: Host Header - placeholder: e.g. www.example.com + path: + placeholder: Request Path e.g. /healthcheck + headers: + label: Host Header port: - label: Listening Port + label: Target Container Port placeholder: e.g. 80 - initializingTimeout: - label: Initializing Timeout + initialDelaySeconds: + label: Delay before initial check unit: ms reinitializingTimeout: label: Reinitializing Timeout unit: ms - interval: + periodSeconds: label: Check Interval - unit: ms - timeout: + timeoutSeconds: label: Check Timeout unit: ms - healthyThreshold: + successThreshold: label: Healthy After unit: successes - unhealthyThreshold: + failureTheshold: label: Unhealthy After unit: failures - strategy: - label: When Unhealthy - none: Take no action - recreate: Delete container and schedule a replacement formKeyValue: addAction: Add Pair @@ -2141,13 +2136,13 @@ formNetwork: formPorts: header: Port Mapping addAction: Add Port - bindAddress: + hostIp: label: Host IP placeholder: "Default: All" - public: + hostPort: label: Host Port placeholder: "e.g. 80" - private: + containerPort: label: Container Port placeholder: "e.g. 8080" protocol:
+ {{#if port.existing}} - {{#if port.bindAddress}} - {{port.bindAddress}} + {{#if port.hostIP}} + {{port.hostIP}} {{else}} {{t 'generic.any'}} {{/if}} {{else}} {{#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}} - {{#if port.bindAddress}} - {{port.bindAddress}} + {{#if port.hostIP}} + {{port.hostIP}} {{else}} {{t 'generic.na'}} {{/if}} @@ -54,23 +54,23 @@   + {{#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}} - {{port.public}} + {{port.hostPort}} {{/if}}   + {{#if port.existing}} -
{{port.private}}
+
{{port.containerPort}}
{{else}} {{#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}} - {{port.private}} + {{port.containerPort}} {{/if}} {{/if}}