mirror of https://github.com/rancher/ui.git
393 lines
9.5 KiB
JavaScript
393 lines
9.5 KiB
JavaScript
import { next } from '@ember/runloop';
|
|
import { alias } from '@ember/object/computed';
|
|
import { inject as service } from '@ember/service';
|
|
import Mixin from '@ember/object/mixin';
|
|
import NewOrEdit from 'shared/mixins/new-or-edit';
|
|
import ManageLabels from 'shared/mixins/manage-labels';
|
|
import { addAction } from 'ui/utils/add-view-action';
|
|
import { get, set, computed, setProperties } from '@ember/object';
|
|
import { ucFirst } from 'shared/utils/util';
|
|
import { formatSi } from 'shared/utils/parse-unit';
|
|
import C from 'ui/utils/constants';
|
|
import { isArray } from '@ember/array';
|
|
import $ from 'jquery';
|
|
|
|
export class DynamicDependentKeysProperty {
|
|
constructor(property) {
|
|
const {
|
|
driver, keyOrKeysToWatch, getDisplayProperty
|
|
} = property;
|
|
|
|
setProperties(this, {
|
|
driver,
|
|
keyOrKeysToWatch,
|
|
});
|
|
|
|
if (getDisplayProperty) {
|
|
set(this, 'getDisplayProperty', getDisplayProperty);
|
|
} else {
|
|
if (keyOrKeysToWatch) {
|
|
let keyToGet = keyOrKeysToWatch;
|
|
|
|
set(this, 'getDisplayProperty', function() {
|
|
return get(this, keyToGet);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Map of location objects -> { driver, keyOrKeysToWatch, getLocation }
|
|
// driver: driver name (e.g. digitial ocean, azure)
|
|
// keyOrKeysToWatch: string | map of strings corresponding to key or keys on config storing the location
|
|
// getLocation: if multiple location keys you may provide an override getting function to fetch and massage display location to your liking
|
|
// Custom UIs should call registerDisplayLocation{new Location} to register new entries.
|
|
const DISPLAY_LOCATIONS = [];
|
|
const DISPLAY_SIZES = [];
|
|
|
|
function _initBuiltInSizes() {
|
|
const CONFIG_SIZE_KEYS = [
|
|
{
|
|
driver: 'aliyunecs',
|
|
keyOrKeysToWatch: 'config.instanceType',
|
|
},
|
|
{
|
|
driver: 'amazonec2',
|
|
keyOrKeysToWatch: 'config.instanceType',
|
|
},
|
|
{
|
|
driver: 'azure',
|
|
keyOrKeysToWatch: 'config.size',
|
|
},
|
|
{
|
|
driver: 'digitalocean',
|
|
keyOrKeysToWatch: 'config.size',
|
|
},
|
|
{
|
|
driver: 'exoscale',
|
|
keyOrKeysToWatch: 'config.instanceProfile',
|
|
},
|
|
{
|
|
driver: 'linode',
|
|
keyOrKeysToWatch: 'config.instanceType',
|
|
},
|
|
{
|
|
driver: 'oci',
|
|
keyOrKeysToWatch: 'config.nodeShape',
|
|
},
|
|
{
|
|
driver: 'packet',
|
|
keyOrKeysToWatch: 'config.plan',
|
|
},
|
|
{
|
|
driver: 'pnap',
|
|
keyOrKeysToWatch: 'config.serverType',
|
|
},
|
|
{
|
|
driver: 'rackspace',
|
|
keyOrKeysToWatch: 'config.flavorId',
|
|
},
|
|
{
|
|
driver: 'vmwarevsphere',
|
|
keyOrKeysToWatch: ['config.memorySize', 'config.cpuCount'],
|
|
getDisplayProperty() {
|
|
const size = formatSi(get(this, 'config.memorySize') * 1048576, 1024, 'iB');
|
|
|
|
return `${ size }, ${ get(this, 'config.cpuCount') } Core`;
|
|
}
|
|
},
|
|
{
|
|
driver: 'harvester',
|
|
keyOrKeysToWatch: null,
|
|
},
|
|
];
|
|
|
|
CONFIG_SIZE_KEYS.forEach((size) => {
|
|
registerDisplaySize(new DynamicDependentKeysProperty(size));
|
|
});
|
|
}
|
|
|
|
function _initBuiltInLocations() {
|
|
const CONFIG_LOCATION_KEYS = [
|
|
{
|
|
driver: 'aliyunecs',
|
|
keyOrKeysToWatch: ['config.region', 'config.zone'],
|
|
getDisplayProperty() {
|
|
return `${ get(this, 'config.region') }${ get(this, 'config.zone') }`
|
|
}
|
|
},
|
|
{
|
|
driver: 'amazonec2',
|
|
keyOrKeysToWatch: ['config.region', 'config.zone'],
|
|
getDisplayProperty() {
|
|
return `${ get(this, 'config.region') }${ get(this, 'config.zone') }`
|
|
}
|
|
},
|
|
{
|
|
driver: 'azure',
|
|
keyOrKeysToWatch: 'config.location',
|
|
},
|
|
{
|
|
driver: 'digitalocean',
|
|
keyOrKeysToWatch: 'config.region',
|
|
},
|
|
{
|
|
driver: 'exoscale',
|
|
keyOrKeysToWatch: 'config.availabilityZone',
|
|
},
|
|
{
|
|
driver: 'linode',
|
|
keyOrKeysToWatch: 'config.region',
|
|
},
|
|
{
|
|
driver: 'packet',
|
|
keyOrKeysToWatch: 'config.facilityCode',
|
|
},
|
|
{
|
|
driver: 'pnap',
|
|
keyOrKeysToWatch: 'config.serverLocation',
|
|
},
|
|
{
|
|
driver: 'rackspace',
|
|
keyOrKeysToWatch: 'config.region',
|
|
},
|
|
{
|
|
driver: 'vmwarevsphere',
|
|
keyOrKeysToWatch: null,
|
|
},
|
|
{
|
|
driver: 'harvester',
|
|
keyOrKeysToWatch: null,
|
|
},
|
|
];
|
|
|
|
CONFIG_LOCATION_KEYS.forEach((location) => {
|
|
registerDisplayLocation(new DynamicDependentKeysProperty(location));
|
|
});
|
|
}
|
|
|
|
_initBuiltInLocations();
|
|
_initBuiltInSizes();
|
|
|
|
export function getDisplayLocation(driver) {
|
|
return DISPLAY_LOCATIONS.findBy('driver', driver);
|
|
}
|
|
|
|
export function getDisplaySize(driver) {
|
|
return DISPLAY_SIZES.findBy('driver', driver );
|
|
}
|
|
|
|
export function registerDisplayLocation(location) {
|
|
DISPLAY_LOCATIONS.push(location)
|
|
}
|
|
|
|
export function registerDisplaySize(size) {
|
|
DISPLAY_SIZES.push(size);
|
|
}
|
|
|
|
export default Mixin.create(NewOrEdit, ManageLabels, {
|
|
intl: service(),
|
|
scope: service(),
|
|
settings: service(),
|
|
router: service(),
|
|
globalStore: service(),
|
|
|
|
driverName: null,
|
|
errors: null,
|
|
showEngineUrl: true, // On some drivers this isn't configurable
|
|
model: null,
|
|
labelResource: alias('model'),
|
|
|
|
|
|
actions: {
|
|
errorHandler(err, shouldClearPreviousErrors = false) {
|
|
let { errors } = this;
|
|
|
|
if (shouldClearPreviousErrors) {
|
|
errors = set(this, 'errors', []);
|
|
}
|
|
|
|
if (errors) {
|
|
if (isArray(err)) {
|
|
errors.pushObjects(err);
|
|
} else {
|
|
errors.pushObject(err);
|
|
}
|
|
} else {
|
|
errors = [err];
|
|
}
|
|
|
|
set(this, 'errors', errors);
|
|
},
|
|
|
|
finishAndSelectCloudCredential() {},
|
|
|
|
addLabel: addAction('addLabel', '.key'),
|
|
|
|
setLabels(labels) {
|
|
let out = {};
|
|
|
|
labels.forEach((row) => {
|
|
out[row.key] = row.value;
|
|
});
|
|
|
|
set(this, 'labelResource.labels', out);
|
|
},
|
|
|
|
cancel() {
|
|
if (this.close) {
|
|
this.close();
|
|
}
|
|
}
|
|
},
|
|
|
|
init() {
|
|
this._super(...arguments);
|
|
|
|
if ( !get(this, 'editing') && typeof get(this, 'bootstrap') === 'function') {
|
|
this.initEngineUrl();
|
|
this.bootstrap();
|
|
}
|
|
|
|
set(this, 'model.namespaceId', 'fixme'); // @TODO-2.0
|
|
},
|
|
|
|
bootstrap() {
|
|
// Populate the appropriate *Config field with defaults for your driver
|
|
},
|
|
|
|
cloudCredentials: computed('model.cloudCredentialId', 'driverName', function() {
|
|
const { driverName } = this;
|
|
|
|
return this.globalStore.all('cloudcredential').filter((cc) => {
|
|
switch (driverName) {
|
|
case 'digitalocean':
|
|
if (get(cc, 'isDo')) {
|
|
return cc;
|
|
}
|
|
break;
|
|
case 'amazonec2':
|
|
if (get(cc, 'isAmazon')) {
|
|
return cc;
|
|
}
|
|
break;
|
|
case 'azure':
|
|
if (get(cc, 'isAzure')) {
|
|
return cc;
|
|
}
|
|
break;
|
|
case 'harvester':
|
|
if (get(cc, 'isHarvester')) {
|
|
return cc;
|
|
}
|
|
break;
|
|
case 'linode':
|
|
if (get(cc, 'isLinode')) {
|
|
return cc;
|
|
}
|
|
break;
|
|
case 'oci':
|
|
if (get(cc, 'isOCI')) {
|
|
return cc;
|
|
}
|
|
break;
|
|
case 'pnap':
|
|
if (get(cc, 'isPNAP')) {
|
|
return cc;
|
|
}
|
|
break;
|
|
case 'vmwarevsphere':
|
|
if (get(cc, 'isVMware')) {
|
|
return cc;
|
|
}
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
}).sortBy('name');
|
|
}),
|
|
|
|
driverOptionsTitle: computed('driverName', 'intl.locale', function() {
|
|
const intl = get(this, 'intl');
|
|
const driver = get(this, 'driverName');
|
|
const key = `nodeDriver.displayName.${ driver }`;
|
|
let name = ucFirst(driver);
|
|
|
|
if ( intl.exists(key) ) {
|
|
name = intl.t(key);
|
|
}
|
|
|
|
return intl.t('nodeDriver.driverOptions', { driver: name });
|
|
}),
|
|
|
|
templateOptionsTitle: computed('settings.appName', 'intl.locale', function() {
|
|
const intl = get(this, 'intl');
|
|
const appName = get(this, 'settings.appName');
|
|
|
|
return intl.t('nodeDriver.templateOptions', { appName });
|
|
}),
|
|
|
|
initEngineUrl() {
|
|
let engineInstallURL = null;
|
|
let engineRegistryMirror = [];
|
|
|
|
if ( get(this, 'showEngineUrl') ) {
|
|
engineInstallURL = get(this, `settings.${ C.SETTING.ENGINE_URL }`) || '';
|
|
}
|
|
|
|
setProperties(this, {
|
|
'model.engineInstallURL': engineInstallURL,
|
|
'model.engineRegistryMirror': engineRegistryMirror,
|
|
});
|
|
},
|
|
|
|
didInsertElement() {
|
|
this._super();
|
|
|
|
next(() => {
|
|
try {
|
|
const input = $('INPUT')[0];
|
|
|
|
if ( input ) {
|
|
input.focus();
|
|
}
|
|
} catch (e) {}
|
|
});
|
|
},
|
|
|
|
willSave() {
|
|
get(this, 'model').clearConfigsExcept(`${ get(this, 'driverName') }Config`);
|
|
|
|
return this._super(...arguments);
|
|
},
|
|
|
|
validateCloudCredentials() {
|
|
const driversToValidate = ['amazonec2', 'azure', 'digitalocean', 'linode', 'pnap', 'vmwarevsphere', 'harvester'];
|
|
let { driverName } = this;
|
|
let { cloudCredentialId } = this.model;
|
|
let valid = false;
|
|
|
|
if (driversToValidate.includes(driverName) && cloudCredentialId) {
|
|
valid = true;
|
|
} else {
|
|
valid = false;
|
|
}
|
|
|
|
return valid;
|
|
},
|
|
|
|
doneSaving() {
|
|
// This triggers nodetemplates to recompute the display size/location
|
|
get(this, 'model').notifyPropertyChange('displaySize');
|
|
get(this, 'model').notifyPropertyChange('displayLocation');
|
|
|
|
if (this.saved) {
|
|
this.saved();
|
|
}
|
|
|
|
if (this.close) {
|
|
this.close()
|
|
}
|
|
},
|
|
});
|