ui/lib/shared/addon/components/cluster-driver/driver-oracleoke/component.js

393 lines
12 KiB
JavaScript

import Component from '@ember/component'
import ClusterDriver from 'shared/mixins/cluster-driver';
import layout from './template';
import { equal } from '@ember/object/computed'
import { compare } from 'shared/utils/parse-version';
import { get, set, computed, setProperties } from '@ember/object';
import { inject as service } from '@ember/service';
const regionMap = {
'Mumbai': 'ap-mumbai-1',
'Seoul': 'ap-seoul-1',
'Tokyo': 'ap-tokyo-1',
'Toronto': 'ca-toronto-1',
'Frankfurt': 'eu-frankfurt-1',
'Zurich': 'eu-zurich-1',
'Sao Paolo': 'sa-saopaulo-1',
'London': 'uk-london-1',
'Ashburn': 'us-ashburn-1',
'Phoenix': 'us-phoenix-1',
'Amsterdam': 'eu-amsterdam-1',
'Hyderabad': 'ap-hyderabad-1',
'Jeddah': 'me-jeddah-1',
'Osaka': 'ap-osaka-1',
'Melbourne': 'ap-melbourne-1',
'Sydney': 'ap-sydney-1',
'Chuncheon': 'ap-chuncheon-1',
'Montreal': 'ca-montreal-1',
}
const k8sVersionMap = {
'v1.16.8': 'v1.16.8', // default
'v1.15.7': 'v1.15.7',
'v1.14.8': 'v1.14.8',
}
const vcnIdMap = { quick: 'Quick Create', }
const subnetAccessMap = {
public: 'Public',
private: 'Private',
}
const nodeShapeMap = {
'VM.Standard1.1': 'VM.Standard1.1',
'VM.Standard1.2': 'VM.Standard1.2',
'VM.Standard1.4': 'VM.Standard1.4',
'VM.Standard1.8': 'VM.Standard1.8',
'VM.Standard1.16': 'VM.Standard1.16',
'VM.Standard2.1': 'VM.Standard2.1',
'VM.Standard2.2': 'VM.Standard2.2',
'VM.Standard2.4': 'VM.Standard2.4',
'VM.Standard2.8': 'VM.Standard2.8',
'VM.Standard2.16': 'VM.Standard2.16',
'VM.Standard2.24': 'VM.Standard2.24',
'BM.Standard.E2.64': 'BM.Standard.E2.64',
'BM.Standard2.52': 'BM.Standard2.52',
'BM.Standard.B1.44': 'BM.Standard.B1.44',
'BM.DenseIO2.52': 'BM.DenseIO2.52',
'BM.HPC2.36': 'BM.HPC2.36',
'VM.Standard.E2.1.Micro': 'VM.Standard.E2.1.Micro',
'VM.Standard.E2.2': 'VM.Standard.E2.2',
'VM.GPU2.1': 'VM.GPU2.1',
'VM.GPU2.2': 'VM.GPU2.2',
'VM.GPU3.1': 'VM.GPU3.1',
'VM.GPU3.2': 'VM.GPU3.2',
'VM.GPU3.4': 'VM.GPU3.4',
'VM.GPU3.8': 'VM.GPU3.8',
}
const imageMap = {
'Oracle-Linux-7.6': 'Oracle-Linux-7.6',
'Oracle-Linux-7.5': 'Oracle-Linux-7.5',
'Oracle-Linux-7.4': 'Oracle-Linux-7.4',
}
export default Component.extend(ClusterDriver, {
intl: service(),
layout,
configField: 'okeEngineConfig',
instanceConfig: '',
step: 1,
lanChanged: null,
refresh: false,
vcnCreationMode: '',
vpcs: null,
subnets: null,
eipIds: null,
nodeFlavors: null,
keypairs: null,
availableZones: null,
isNew: equal('mode', 'new'),
editing: equal('mode', 'edit'),
init() {
this._super(...arguments);
let config = get(this, 'cluster.okeEngineConfig');
if ( !config ) {
config = this.get('globalStore').createRecord({
type: 'okeEngineConfig',
secretKey: '',
clusterName: '',
vcnCidr: '10.0.0.0/16',
kubernetesVersion: 'v1.16.8',
region: 'us-phoenix-1',
vcn: '',
securityListId: '',
subnetAccess: 'public',
cpu: 0,
memory: 0,
quantityPerSubnet: 1,
quantityOfNodeSubnets: 1,
});
set(this, 'cluster.okeEngineConfig', config);
}
// init cpu and memory
const {
cpu,
memory
} = get(this, 'config');
if (cpu && memory) {
set(this, 'instanceConfig', `${ get(this, 'config.cpu') }/${ get(this, 'config.memory') }`);
}
},
actions: {
// TODO implement authenticateOCI
authenticateOCI(cb) {
setProperties(this, {
'errors': null,
'config.userOcid': (get(this, 'config.userOcid') || '').trim(),
'config.secretKey': (get(this, 'config.secretKey') || '').trim(),
'config.privateKeyPassphrase': (get(this, 'config.privateKeyPassphrase') || '').trim(),
'config.region': (get(this, 'config.region')),
});
set(this, 'step', 2);
cb(true);
},
// TODO re-implement loadNodeConfig
loadNodeConfig(cb) {
set(this, 'step', 3);
cb(true);
},
// TODO implement loadInstanceConfig
loadInstanceConfig(cb) {
set(this, 'errors', null);
set(this, 'step', 4);
cb(true);
},
upgradeCluster(cb) {
setProperties(this, { 'errors': null });
const errors = get(this, 'errors') || [];
const intl = get(this, 'intl');
const quantityPerSubnet = get(this, 'config.quantityPerSubnet');
const kubernetesVersion = get(this, 'config.kubernetesVersion');
if (!quantityPerSubnet) {
errors.push(intl.t('clusterNew.oke.quantityPerSubnet.required'));
} else {
const maxNodeCount = get(this, 'config.maxNodeCount');
if (!/^\d+$/.test(quantityPerSubnet) || parseInt(quantityPerSubnet, 10) < 0 || parseInt(quantityPerSubnet, 10) > maxNodeCount) {
errors.push(intl.t('clusterNew.oke.quantityPerSubnet.error', { max: maxNodeCount }));
}
}
if (!kubernetesVersion) {
errors.push(intl.t('clusterNew.oke.version.required'));
}
if (errors.length > 0) {
set(this, 'errors', errors);
cb();
return;
}
this.send('driverSave', cb);
},
save(cb) {
setProperties(this, {
'errors': null,
'otherErrors': null,
'clusterErrors': null,
});
const errors = get(this, 'errors') || [];
if (errors.length > 0) {
set(this, 'errors', errors);
cb(false);
return;
}
if (!this.validate()) {
cb(false);
return;
}
if (get(this, 'config.nodeImage') === '') {
set(this, 'config.nodeImage', imageMap['Oracle-Linux-7.6']);
}
if (get(this, 'config.vcnCompartmentId') === '') {
set(this, 'config.vcnCompartmentId', get(this, 'config.compartmentId'));
}
if (get(this, 'config.subnetAccess') === 'public') {
set(this, 'config.enablePrivateNodes', false);
} else {
set(this, 'config.enablePrivateNodes', true);
}
this.send('driverSave', cb);
},
cancel() {
get(this, 'router').transitionTo('global-admin.clusters.index');
},
cpuAndMemoryChanged(item) {
setProperties(this, {
'config.cpu': item.raw.cpuCount,
'config.memory': item.raw.memoryCapacityInGB
});
}
},
maxNodeCount: computed('clusterQuota.slave', () => {
return 256;
}),
regionChoices: Object.entries(regionMap).map((e) => ({
label: e[0],
value: e[1]
})),
selectedRegion: computed('config.region', function() {
const region = get(this, 'config.region');
return region;
}),
vcnChoices: Object.entries(vcnIdMap).map((e) => ({
label: e[1],
value: e[0]
})),
selectedVCN: computed('config.vcnId', function() {
const vcnId = get(this, 'config.vcnId');
return vcnId && vcnIdMap[vcnId];
}),
subnetAccessChoices: Object.entries(subnetAccessMap).map((e) => ({
label: e[1],
value: e[0]
})),
selectedSubnetAccess: computed('config.subnetAccess', function() {
const subnetAccess = get(this, 'config.subnetAccess');
return subnetAccess && subnetAccessMap[subnetAccess];
}),
nodeShapeChoices: Object.entries(nodeShapeMap).map((e) => ({
label: e[1],
value: e[0]
})),
selectednodeShape: computed('config.nodeShape', function() {
const nodeShape = get(this, 'config.nodeShape');
return nodeShape && nodeShapeMap[nodeShape];
}),
imageChoices: Object.entries(imageMap).map((e) => ({
label: e[1],
value: e[0]
})),
selectedImage: computed('config.nodeImage', function() {
const nodeImage = get(this, 'config.nodeImage');
return nodeImage && imageMap[nodeImage];
}),
k8sVersionChoices: Object.entries(k8sVersionMap).map((e) => ({
label: e[1],
value: e[0]
})),
k8sUpgradeVersionChoices: computed('config.kubernetesVersion', function() {
let supportedVersions = Object.assign({}, k8sVersionMap);
var currentVersion = get(this, 'config.kubernetesVersion');
Object.keys(supportedVersions)
.filter((key) => (compare(key, currentVersion) < 0))
.forEach((key) => delete supportedVersions[key]);
return Object.entries(supportedVersions).map((e) => ({
label: e[1],
value: e[0]
}));
}),
selectedk8sVersion: computed('config.kubernetesVersion', function() {
const k8sVersion = get(this, 'config.kubernetesVersion');
return k8sVersion && k8sVersionMap[k8sVersion];
}),
canAuthenticate: computed('config.tenancyId', 'config.compartmentId', 'config.userOcid', 'config.fingerprint', 'config.privateKeyContents', function() {
return get(this, 'config.tenancyId') && get(this, 'config.compartmentId') && get(this, 'config.userOcid') && get(this, 'config.fingerprint') && get(this, 'config.privateKeyContents') ? false : true;
}),
canSaveVCN: computed('vcnCreationMode', 'config.vcnName', 'config.loadBalancerSubnetName1', 'config.loadBalancerSubnetName2', 'config.subnetAccess', 'config.vcnCidr', function() {
const mode = get(this, 'vcnCreationMode');
if (mode === 'Quick') {
return false;
} else if (mode === 'Existing') {
// Driver will use the same compartment as the cluster if not set.
return (get(this, 'config.vcnName') && get(this, 'config.loadBalancerSubnetName1')) ? false : true;
} else if (mode === 'Custom') {
return (get(this, 'config.subnetAccess') && get(this, 'config.vcnCidr')) ? false : true;
}
return true;
}),
canCreateCluster: computed('config.nodeShape', function() {
return get(this, 'config.nodeShape') ? false : true;
}),
// Add custom validation beyond what can be done from the config API schema
validate() {
// Get generic API validation errors
this._super();
var errors = get(this, 'errors') || [];
if (!get(this, 'cluster.name')) {
errors.push('Name is required');
}
const tenancyId = get(this, 'config.tenancyId');
if (!tenancyId.startsWith('ocid1.tenancy')) {
errors.push('A valid tenancy OCID is required');
}
const compartmentId = get(this, 'config.compartmentId');
if (!compartmentId.startsWith('ocid1.compartment') && !compartmentId.startsWith('ocid1.tenancy')) {
errors.push('A valid compartment OCID is required');
}
const userOcid = get(this, 'config.userOcid');
if (!userOcid.startsWith('ocid1.user')) {
errors.push('A valid user OCID is required');
}
// TODO Add more specific errors
// Set the array of errors for display,
// and return true if saving should continue.
if (get(errors, 'length')) {
set(this, 'errors', errors);
return false;
} else {
set(this, 'errors', null);
return true;
}
},
willSave() {
if (get(this, 'mode') === 'new') {
if (get(this, 'config.nodeImage') === '') {
set(this, 'config.nodeImage', imageMap['Oracle-Linux-7.6']);
}
if (get(this, 'config.vcnCompartmentId') === '') {
set(this, 'config.vcnCompartmentId', get(this, 'config.compartmentId'));
}
if (get(this, 'config.subnetAccess') === 'public') {
set(this, 'config.enablePrivateNodes', false);
} else {
set(this, 'config.enablePrivateNodes', true);
}
}
return this._super(...arguments);
},
});