pgadmin4/web/pgadmin/misc/cloud/static/js/biganimal.js

336 lines
12 KiB
JavaScript

/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2023, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import React from 'react';
import pgAdmin from 'sources/pgadmin';
import { getNodeAjaxOptions, getNodeListById } from 'pgbrowser/node_ajax';
import {BigAnimalClusterSchema, BigAnimalDatabaseSchema, BigAnimalClusterTypeSchema} from './biganimal_schema.ui';
import SchemaView from '../../../../static/js/SchemaView';
import url_for from 'sources/url_for';
import getApiInstance from '../../../../static/js/api_instance';
import { isEmptyString } from 'sources/validators';
import PropTypes from 'prop-types';
import gettext from 'sources/gettext';
import { makeStyles } from '@material-ui/core/styles';
import { AWSIcon, MSAzureIcon } from '../../../../static/js/components/ExternalIcon';
const useStyles = makeStyles(() =>
({
providerHeight: {
height: '5em',
},
AwsIcon: {
width: '6rem',
}
}),
);
const axiosApi = getApiInstance();
export function getProviderOptions() {
return new Promise((resolve, reject) => {
axiosApi.get(url_for('biganimal.providers'))
.then((res) => {
if (res.data.data) {
let _options= [],
_options_label = {'azure': <MSAzureIcon key='1' />,
'aws': <AWSIcon style={{width: '6rem'}} key = '2'/>};
_.forEach(res.data.data, (val) => {
_options.push({
'label': _options_label[val['value']],
'value': val['value'],
'disabled': !val['connected']
});
});
resolve(_options);
}
})
.catch((error) => {
reject(gettext(`Error while getting the biganimal providers: ${error.response.data.errormsg}`));
});
});
}
// BigAnimal Cluster Type
export function BigAnimalClusterType(props) {
const [bigAnimalClusterType, setBigAnimalClusterType] = React.useState();
const classes = useStyles();
React.useMemo(() => {
const bigAnimalClusterTypeSchema = new BigAnimalClusterTypeSchema({
providers: ()=>getNodeAjaxOptions('biganimal_providers', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, {
useCache:false,
cacheNode: 'server',
customGenerateUrl: ()=>{
return url_for('biganimal.providers');
}
}),
}, {
nodeInfo: props.nodeInfo,
nodeData: props.nodeData,
hostIP: props.hostIP,
classes: classes,
bigAnimalProviders: props.bigAnimalProviders,
});
setBigAnimalClusterType(bigAnimalClusterTypeSchema);
}, [props.cloudProvider]);
return <SchemaView
formType={'dialog'}
getInitData={() => { /*This is intentional (SonarQube)*/ }}
viewHelperProps={{ mode: 'create' }}
schema={bigAnimalClusterType}
showFooter={false}
isTabView={false}
onDataChange={(isChanged, changedData) => {
props.setBigAnimalClusterTypeData(changedData);
}}
/>;
}
BigAnimalClusterType.propTypes = {
nodeInfo: PropTypes.object,
nodeData: PropTypes.object,
cloudProvider: PropTypes.string,
setBigAnimalClusterTypeData: PropTypes.func,
hostIP: PropTypes.string,
bigAnimalProviders: PropTypes.object,
};
// BigAnimal Instance
export function BigAnimalInstance(props) {
const [bigAnimalInstance, setBigAnimalInstance] = React.useState();
React.useMemo(() => {
const bigAnimalSchema = new BigAnimalClusterSchema({
regions: (provider_id)=>getNodeAjaxOptions('biganimal_regions', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, {
useCache:false,
cacheNode: 'server',
customGenerateUrl: ()=>{
return url_for('biganimal.regions', {'provider_id': provider_id || 0});
}
}),
instance_types: (region_id, provider_id)=>{
if (isEmptyString(region_id)) return [];
return getNodeAjaxOptions('biganimal_instance_types', pgAdmin.Browser.Nodes['server'],
props.nodeInfo, props.nodeData, {
useCache:false,
cacheNode: 'server',
customGenerateUrl: ()=>{
return url_for('biganimal.instance_types', {'region_id': region_id || 0, 'provider_id': provider_id || 0});
}
});
},
volume_types: (region_id, provider_id)=>{
if (isEmptyString(region_id)) return [];
return getNodeAjaxOptions('biganimal_volume_types', pgAdmin.Browser.Nodes['server'],
props.nodeInfo, props.nodeData, {
useCache:false,
cacheNode: 'server',
customGenerateUrl: ()=>{
return url_for('biganimal.volume_types', {'region_id': region_id || 0, 'provider_id': provider_id || 0});
}
});
},
volume_properties: (region_id, provider_id, volume_type)=>{
if (isEmptyString(region_id) || isEmptyString(volume_type)) return [];
return getNodeAjaxOptions('biganimal_volume_properties', pgAdmin.Browser.Nodes['server'],
props.nodeInfo, props.nodeData, {
useCache:false,
cacheNode: 'server',
customGenerateUrl: ()=>{
return url_for('biganimal.volume_properties', {'region_id': region_id || 0, 'provider_id': provider_id || 0, 'volume_type': volume_type || ''});
}
});
},
}, {
nodeInfo: props.nodeInfo,
nodeData: props.nodeData,
hostIP: props.hostIP,
provider: props.bigAnimalClusterTypeData.provider,
});
setBigAnimalInstance(bigAnimalSchema);
}, [props.cloudProvider]);
return <SchemaView
formType={'dialog'}
getInitData={() => { /*This is intentional (SonarQube)*/ }}
viewHelperProps={{ mode: 'create' }}
schema={bigAnimalInstance}
showFooter={false}
isTabView={false}
onDataChange={(isChanged, changedData) => {
props.setBigAnimalInstanceData(changedData);
}}
/>;
}
BigAnimalInstance.propTypes = {
nodeInfo: PropTypes.object,
nodeData: PropTypes.object,
cloudProvider: PropTypes.string,
setBigAnimalInstanceData: PropTypes.func,
hostIP: PropTypes.string,
bigAnimalClusterTypeData: PropTypes.object,
};
// BigAnimal Database
export function BigAnimalDatabase(props) {
const [bigAnimalDatabase, setBigAnimalDatabase] = React.useState();
React.useMemo(() => {
const bigAnimalDBSchema = new BigAnimalDatabaseSchema({
db_types: ()=>getNodeAjaxOptions('biganimal_db_types', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, {
useCache:false,
cacheNode: 'server',
customGenerateUrl: ()=>{
return url_for('biganimal.db_types');
}
}),
db_versions: (cluster_type, pg_type)=>getNodeAjaxOptions('biganimal_db_versions', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, {
useCache:false,
cacheNode: 'server',
customGenerateUrl: ()=>{
return url_for('biganimal.db_versions', {'cluster_type': cluster_type || 'single', 'pg_type': pg_type || 'pg'});
}
}),
server_groups: ()=>getNodeListById(pgAdmin.Browser.Nodes['server_group'], props.nodeInfo, props.nodeData),
}, {
gid: props.nodeInfo['server_group']._id,
cluster_type: props.bigAnimalClusterTypeData.cluster_type,
});
setBigAnimalDatabase(bigAnimalDBSchema);
}, [props.cloudProvider]);
return <SchemaView
formType={'dialog'}
getInitData={() => { /*This is intentional (SonarQube)*/ }}
viewHelperProps={{ mode: 'create' }}
schema={bigAnimalDatabase}
showFooter={false}
isTabView={false}
onDataChange={(isChanged, changedData) => {
props.setBigAnimalDatabaseData(changedData);
}}
/>;
}
BigAnimalDatabase.propTypes = {
nodeInfo: PropTypes.object,
nodeData: PropTypes.object,
cloudProvider: PropTypes.string,
setBigAnimalDatabaseData: PropTypes.func,
bigAnimalClusterTypeData: PropTypes.object
};
export function validateBigAnimal() {
return new Promise((resolve, reject)=>{
let _url = url_for('biganimal.verification');
axiosApi.get(_url)
.then((res) => {
if (res.data.data) {
resolve(res.data.data);
}
})
.catch((error) => {
reject(`Error while fetching EDB BigAnimal verification URI: ${error.response.data.errormsg}`);
});
});
}
function createData(name, value) {
if (typeof(value) == 'boolean') {
value = (value === true) ? 'True' : 'False';
}
return { name, value };
}
export function getBigAnimalSummary(cloud, bigAnimalClusterTypeData, bigAnimalInstanceData, bigAnimalDatabaseData) {
const rows1 = [
createData(gettext('Cloud'), cloud),
createData(gettext('Instance name'), bigAnimalInstanceData.name),
createData(gettext('Region'), bigAnimalInstanceData.region),
createData(gettext('Cluster type'), bigAnimalInstanceData.cloud_type),
createData(gettext('Public IPs'), bigAnimalInstanceData.biganimal_public_ip),
];
let instance_size = bigAnimalInstanceData.instance_size.split('||');
const rows2 = [
createData(gettext('Cluster type'), bigAnimalClusterTypeData.cluster_type),
createData(gettext('No. of Standby Replicas'), bigAnimalClusterTypeData.replicas),
createData(gettext('Provider'), bigAnimalClusterTypeData.provider),
];
const rows3 = [
createData(gettext('Instance type'), bigAnimalInstanceData.instance_type),
createData(gettext('Instance series'), bigAnimalInstanceData.instance_series),
createData(gettext('Instance size'), instance_size[0]),
];
const rows4 = [
createData(gettext('Volume type'), bigAnimalInstanceData.volume_type),
createData(gettext('Volume size'), bigAnimalInstanceData.volume_size),
createData(gettext('Volume IOPS'), bigAnimalInstanceData.volume_IOPS),
];
const rows5 = [
createData(gettext('Password'), 'xxxxxxx'),
createData(gettext('Database Type'), bigAnimalDatabaseData.database_type),
createData(gettext('Database Version'), bigAnimalDatabaseData.postgres_version),
];
return [rows1, rows2, rows3, rows4, rows5];
}
export function validateBigAnimalStep2(cloudTypeDetails) {
let isError = false;
if (isEmptyString(cloudTypeDetails.cluster_type) || isEmptyString(cloudTypeDetails.provider) ||
(cloudTypeDetails.cluster_type == 'ha' && cloudTypeDetails.replicas == 0)
) {
isError = true;
}
return isError;
}
export function validateBigAnimalStep3(cloudDetails) {
let isError = false;
if (isEmptyString(cloudDetails.name) ||
isEmptyString(cloudDetails.region) || isEmptyString(cloudDetails.instance_type) ||
isEmptyString(cloudDetails.instance_series)|| isEmptyString(cloudDetails.instance_size) ||
isEmptyString(cloudDetails.volume_type) || (cloudDetails.provider != 'aws' && isEmptyString(cloudDetails.volume_properties)) ) {
isError = true;
}
if (cloudDetails.provider == 'aws') {
if (isEmptyString(cloudDetails.volume_IOPS) || isEmptyString(cloudDetails.volume_IOPS) || (cloudDetails.volume_IOPS != 'io2' &&
(cloudDetails.volume_size < 1 || cloudDetails.volume_size > 16384)) ||
(cloudDetails.volume_IOPS == 'io2' && (cloudDetails.volume_size < 4 || cloudDetails.volume_size > 16384)) ||
(cloudDetails.volume_IOPS != 'io2' && cloudDetails.volume_IOPS != 3000) ||
(cloudDetails.volume_IOPS == 'io2' && (cloudDetails.volume_IOPS < 100 || cloudDetails.volume_IOPS > 2000))) {
isError = true;
}
}
return isError;
}
export function validateBigAnimalStep4(cloudDBDetails, nodeInfo) {
let isError = false;
if (isEmptyString(cloudDBDetails.password) ||
isEmptyString(cloudDBDetails.database_type) || isEmptyString(cloudDBDetails.postgres_version)) {
isError = true;
}
if (isEmptyString(cloudDBDetails.gid)) cloudDBDetails.gid = nodeInfo['server_group']._id;
return isError;
}