github.com/hernad/nomad@v1.6.112/ui/app/services/system.js (about) 1 /** 2 * Copyright (c) HashiCorp, Inc. 3 * SPDX-License-Identifier: MPL-2.0 4 */ 5 6 import Service, { inject as service } from '@ember/service'; 7 import { computed } from '@ember/object'; 8 import { alias } from '@ember/object/computed'; 9 import PromiseObject from '../utils/classes/promise-object'; 10 import PromiseArray from '../utils/classes/promise-array'; 11 import { namespace } from '../adapters/application'; 12 import jsonWithDefault from '../utils/json-with-default'; 13 import classic from 'ember-classic-decorator'; 14 import { task } from 'ember-concurrency'; 15 16 @classic 17 export default class SystemService extends Service { 18 @service token; 19 @service store; 20 21 @computed('activeRegion') 22 get leader() { 23 const token = this.token; 24 25 return PromiseObject.create({ 26 promise: token 27 .authorizedRequest(`/${namespace}/status/leader`) 28 .then((res) => res.json()) 29 .then((rpcAddr) => ({ rpcAddr })) 30 .then((leader) => { 31 // Dirty self so leader can be used as a dependent key 32 this.notifyPropertyChange('leader.rpcAddr'); 33 return leader; 34 }), 35 }); 36 } 37 38 @computed 39 get agent() { 40 const token = this.token; 41 return PromiseObject.create({ 42 promise: token 43 .authorizedRawRequest(`/${namespace}/agent/self`) 44 .then(jsonWithDefault({})) 45 .then((agent) => { 46 if (agent?.config?.Version) { 47 const { Version, VersionPrerelease, VersionMetadata } = 48 agent.config.Version; 49 agent.version = Version; 50 if (VersionPrerelease) 51 agent.version = `${agent.version}-${VersionPrerelease}`; 52 if (VersionMetadata) 53 agent.version = `${agent.version}+${VersionMetadata}`; 54 } 55 return agent; 56 }), 57 }); 58 } 59 60 @computed 61 get defaultRegion() { 62 const token = this.token; 63 return PromiseObject.create({ 64 promise: token 65 .authorizedRawRequest(`/${namespace}/agent/members`) 66 .then(jsonWithDefault({})) 67 .then((json) => { 68 return { region: json.ServerRegion }; 69 }), 70 }); 71 } 72 73 @computed 74 get regions() { 75 const token = this.token; 76 77 return PromiseArray.create({ 78 promise: token 79 .authorizedRawRequest(`/${namespace}/regions`) 80 .then(jsonWithDefault([])), 81 }); 82 } 83 84 @computed('regions.[]') 85 get activeRegion() { 86 const regions = this.regions; 87 const region = window.localStorage.nomadActiveRegion; 88 89 if (regions.includes(region)) { 90 return region; 91 } 92 93 return null; 94 } 95 96 set activeRegion(value) { 97 if (value == null) { 98 window.localStorage.removeItem('nomadActiveRegion'); 99 return; 100 } else { 101 // All localStorage values are strings. Stringify first so 102 // the return value is consistent with what is persisted. 103 const strValue = value + ''; 104 window.localStorage.nomadActiveRegion = strValue; 105 } 106 } 107 108 @computed('regions.[]') 109 get shouldShowRegions() { 110 return this.get('regions.length') > 1; 111 } 112 113 @computed('activeRegion', 'defaultRegion.region', 'shouldShowRegions') 114 get shouldIncludeRegion() { 115 return ( 116 this.shouldShowRegions && 117 this.activeRegion !== this.get('defaultRegion.region') 118 ); 119 } 120 121 @computed('activeRegion') 122 get namespaces() { 123 return PromiseArray.create({ 124 promise: this.store 125 .findAll('namespace') 126 .then((namespaces) => namespaces.compact()), 127 }); 128 } 129 130 @computed('namespaces.[]') 131 get shouldShowNamespaces() { 132 const namespaces = this.namespaces.toArray(); 133 return ( 134 namespaces.length && 135 namespaces.some((namespace) => namespace.get('id') !== 'default') 136 ); 137 } 138 139 @task(function* () { 140 const emptyLicense = { License: { Features: [] } }; 141 142 try { 143 return yield this.token 144 .authorizedRawRequest(`/${namespace}/operator/license`) 145 .then(jsonWithDefault(emptyLicense)); 146 } catch (e) { 147 return emptyLicense; 148 } 149 }) 150 fetchLicense; 151 152 @task(function* () { 153 try { 154 const request = yield this.token.authorizedRequest('/v1/search/fuzzy', { 155 method: 'POST', 156 body: JSON.stringify({ 157 Text: 'feature-detection-query', 158 Context: 'namespaces', 159 }), 160 }); 161 162 return request.ok; 163 } catch (e) { 164 return false; 165 } 166 }) 167 checkFuzzySearchPresence; 168 169 @alias('fetchLicense.lastSuccessful.value') license; 170 @alias('checkFuzzySearchPresence.last.value') fuzzySearchEnabled; 171 172 @computed('license.License.Features.[]') 173 get features() { 174 return this.get('license.License.Features') || []; 175 } 176 }