import { computed, get } from '@ember/object'; import { or } from '@ember/object/computed'; import Resource from 'ember-api-store/models/resource'; import { download } from 'shared/utils/util'; import C from 'ui/utils/constants'; import StateCounts from 'ui/mixins/state-counts'; import { inject as service } from "@ember/service"; import { reference } from 'ember-api-store/utils/denormalize'; import ResourceUsage from 'shared/mixins/resource-usage'; var Node = Resource.extend(StateCounts, ResourceUsage, { type: 'node', modalService: service('modal'), settings: service(), prefs: service(), router: service(), globalStore: service(), clusterStore: service(), intl: service(), cluster: reference('clusterId','cluster'), nodePool: reference('nodePoolId'), init() { this._super(...arguments); this.defineStateCounts('arrangedInstances', 'instanceStates', 'instanceCountSort'); }, actions: { activate: function() { return this.doAction('activate'); }, deactivate: function() { return this.doAction('deactivate'); }, promptEvacuate: function() { get(this,'modalService').toggleModal('modal-host-evacuate', { model: [this] }); }, evacuate: function() { return this.doAction('evacuate'); }, newContainer: function() { get(this,'router').transitionTo('containers.run', {queryParams: {hostId: get(this,'model.id')}}); }, edit: function() { get(this,'modalService').toggleModal('modal-edit-host', this); }, nodeConfig: function() { var url = this.linkFor('nodeConfig'); if ( url ) { download(url); } } }, availableActions: computed('links.{nodeConfig}', function() { let l = get(this,'links'); let out = [ { label: 'action.nodeConfig', icon: 'icon icon-download', action: 'nodeConfig', enabled: !!l.nodeConfig}, { divider: true }, ]; return out; }), displayIp: or('externalIpAddress','ipAddress'), displayName: computed('name','nodeName','requestedHostname','id', function() { let name = get(this,'name'); if ( name ) { return name; } name = get(this,'nodeName'); if ( name ) { if ( name.match(/[a-z]/i) ) { name = name.replace(/\..*$/,''); } return name; } name = get(this,'requestedHostname'); if ( name ) { return name; } return '('+get(this,'id')+')'; }), rolesArray: computed('etcd','controlPlane','worker', function() { return ['etcd','controlPlane','worker'].filter(x => !!get(this,x)); }), displayRoles: computed('intl.locale','rolesArray.[]', function() { const intl = get(this, 'intl'); const roles = get(this, 'rolesArray'); if ( roles.length >= 3 ) { return [intl.t('generic.all')]; } return roles.map(role => { let key = `model.machine.role.${role}`; if ( intl.exists(key) ) { return intl.t(key); } return key; }); }), sortRole: computed('rolesArray.[]', function() { let roles = get(this, 'rolesArray'); if ( roles.length >= 3 ) { return 1; } if ( roles.includes('controlPlane') ) { return 2; } if ( roles.includes('etcd') ) { return 3; } return 4; }), isUnschedulable: computed('taints.@each.{effect,key}', function(){ const taints = get(this, 'taints') || []; return taints.some(taint=> taint.effect === 'NoExecute' && taint.key === 'node-role.kubernetes.io/etcd'); }), osBlurb: computed('info.os.operatingSystem', function() { var out = get(this,'info.os.operatingSystem')||''; out = out.replace(/\s+\(.*?\)/,''); // Remove details in parens out = out.replace(/;.*$/,''); // Or after semicolons out = out.replace('Red Hat Enterprise Linux Server','RHEL'); // That's kinda long return out; }), /* osBlurb: function() { var out = get(this,'info.osInfo.operatingSystem')||''; out = out.replace(/\s+\(.*?\)/,''); // Remove details in parens out = out.replace(/;.*$/,''); // Or after semicolons out = out.replace('Red Hat Enterprise Linux Server','RHEL'); // That's kinda long var hasKvm = (get(this,'labels')||{})[C.LABEL.KVM] === 'true'; if ( hasKvm && out ) { out += ' (with KVM)'; } return out; }.property('info.osInfo.operatingSystem','labels'), osDetail: alias('info.osInfo.operatingSystem'), dockerEngineVersion: function() { if ( get(this,'info.osInfo') ) { */ // return (get(this,'info.osInfo.dockerVersion')||'').replace(/^Docker version\s*/i,'').replace(/,.*/,''); /* } }.property('info.osInfo.dockerVersion'), supportState: function() { let my = get(this,'dockerEngineVersion')||''; my = my.replace(/-(cs|ce|ee)[0-9.-]*$/,''); let supported = get(this,`settings.${C.SETTING.SUPPORTED_DOCKER}`); let newest = get(this,`settings.${C.SETTING.NEWEST_DOCKER}`); if ( !my || !supported || !newest) { return 'unknown'; } else if ( satisfies(my, supported) ) { return 'supported'; } else if ( compare(my, newest) > 0 ) { return 'untested'; } else { return 'unsupported'; } }.property('dockerEngineVersion',`settings.${C.SETTING.SUPPORTED_DOCKER}`,`settings.${C.SETTING.NEWEST_DOCKER}`), dockerDetail: alias('info.osInfo.operatingSystem'), kernelBlurb: function() { if ( get(this,'info.osInfo') ) { return (get(this,'info.osInfo.kernelVersion')||''); } }.property('info.osInfo.kernelVersion'), cpuBlurb: function() { if ( get(this,'info.cpuInfo.count') ) { var ghz = Math.round(get(this,'info.cpuInfo.mhz')/10)/100; if ( get(this,'info.cpuInfo.count') > 1 ) { return get(this,'info.cpuInfo.count')+'x' + ghz + ' GHz'; } else { return ghz + ' GHz'; } } }.property('info.cpuInfo.{count,mhz}'), cpuTooltip: alias('info.cpuInfo.modelName'), memoryBlurb: function() { if ( get(this,'info.memoryInfo') ) { return formatMib(get(this,'info.memoryInfo.memTotal')); } }.property('info.memoryInfo.memTotal'), memoryLimitBlurb: computed('memory', function() { if ( get(this,'memory') ) { return formatSi(get(this,'memory'), 1024, 'iB', 'B'); } }), localStorageBlurb: computed('localStorageMb', function() { if (get(this,'localStorageMb')) { return formatSi(get(this,'localStorageMb'), 1024, 'iB', 'B', 2); // start at 1024^2==MB } }), diskBlurb: function() { var totalMb = 0; // New hotness if ( get(this,'info.diskInfo.fileSystems') ) { var fses = get(this,'info.diskInfo.fileSystems')||[]; Object.keys(fses).forEach((fs) => { totalMb += fses[fs].capacity; }); return formatMib(totalMb); } else if ( get(this,'info.diskInfo.mountPoints') ) { // Old & busted var mounts = get(this,'info.diskInfo.mountPoints')||[]; Object.keys(mounts).forEach((mountPoint) => { totalMb += mounts[mountPoint].total; }); return formatMib(totalMb); } }.property('info.diskInfo.mountPoints.@each.total','info.diskInfo.fileSystems.@each.capacity'), diskDetail: function() { // New hotness if ( get(this,'info.diskInfo.fileSystems') ) { var out = []; var fses = get(this,'info.diskInfo.fileSystems')||[]; Object.keys(fses).forEach((fs) => { out.pushObject(EmberObject.create({label: fs, value: formatMib(fses[fs].capacity)})); }); return out; } }.property('info.diskInfo.fileSystems.@each.capacity'), */ // If you use this you must ensure that services and containers are already in the store // or they will not be pulled in correctly. displayEndpoints: function() { var store = get(this,'clusterStore'); return (get(this,'publicEndpoints')||[]).map((endpoint) => { if ( !endpoint.service ) { endpoint.service = store.getById('service', endpoint.serviceId); } endpoint.instance = store.getById('instance', endpoint.instanceId); return endpoint; }); }.property('publicEndpoints.@each.{ipAddress,port,serviceId,instanceId}'), requireAnyLabelStrings: function() { return ((get(this,'labels')||{})[C.LABEL.REQUIRE_ANY]||'') .split(/\s*,\s*/) .filter((x) => x.length > 0 && x !== C.LABEL.SYSTEM_TYPE); }.property(`labels.${C.LABEL.REQUIRE_ANY}`), }); Node.reopenClass({ defaultSortBy: 'name,hostname', }); export default Node;