///////////////////////////////////////////////////////////// // // pgAdmin 4 - PostgreSQL Tools // // Copyright (C) 2013 - 2024, 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 {CloudInstanceDetailsSchema, CloudDBCredSchema, DatabaseSchema} from './aws_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'; // AWS credentials export function AwsCredentials(props) { const [cloudDBCredInstance, setCloudDBCredInstance] = React.useState(); React.useMemo(() => { const cloudDBCredSchema = new CloudDBCredSchema({ regions: ()=>getNodeAjaxOptions('get_aws_regions', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, { useCache:false, cacheNode: 'server', customGenerateUrl: ()=>{ return url_for('rds.regions'); } }), }); setCloudDBCredInstance(cloudDBCredSchema); }, [props.cloudProvider]); return { /*This is intentional (SonarQube)*/ }} viewHelperProps={{ mode: 'create' }} schema={cloudDBCredInstance} showFooter={false} isTabView={false} onDataChange={(isChanged, changedData) => { props.setCloudDBCred(changedData); }} />; } AwsCredentials.propTypes = { nodeInfo: PropTypes.object, nodeData: PropTypes.object, cloudProvider: PropTypes.string, setCloudDBCred: PropTypes.func, }; // AWS Instance Details export function AwsInstanceDetails(props) { const [cloudInstanceDetailsInstance, setCloudInstanceDetailsInstance] = React.useState(); React.useMemo(() => { const cloudDBInstanceSchema = new CloudInstanceDetailsSchema({ version: ()=>getNodeAjaxOptions('get_aws_db_versions', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, { useCache:false, cacheNode: 'server', customGenerateUrl: ()=>{ return url_for('rds.db_versions'); } }), getInstances: (engine, reload, options) => { return new Promise((resolve, reject)=>{ const api = getApiInstance(); let _url = url_for('rds.db_instances') ; if (engine) _url += '?eng_version=' + engine; if (reload || options === undefined || options.length == 0) { api.get(_url) .then(res=>{ let data = res.data.data; resolve(data); }) .catch((err)=>{ reject(new Error(err)); }); } else { resolve(options); } }); }, instance_type: ()=>getNodeAjaxOptions('get_aws_db_instances', pgAdmin.Browser.Nodes['server'], props.nodeInfo, props.nodeData, { useCache:false, cacheNode: 'server', customGenerateUrl: ()=>{ return url_for('rds.db_instances'); } }), server_groups: ()=>getNodeListById(pgAdmin.Browser.Nodes['server_group'], props.nodeInfo, props.nodeData), }, { gid: props.nodeInfo['server_group']._id, hostIP: props.hostIP, }); setCloudInstanceDetailsInstance(cloudDBInstanceSchema); }, [props.cloudProvider]); return { /*This is intentional (SonarQube)*/ }} viewHelperProps={{ mode: 'create' }} schema={cloudInstanceDetailsInstance} showFooter={false} isTabView={false} onDataChange={(isChanged, changedData) => { props.setCloudInstanceDetails(changedData); }} />; } AwsInstanceDetails.propTypes = { nodeInfo: PropTypes.object, nodeData: PropTypes.object, cloudProvider: PropTypes.string, hostIP: PropTypes.string, setCloudInstanceDetails: PropTypes.func, }; // AWS Database Details export function AwsDatabaseDetails(props) { const [cloudDBInstance, setCloudDBInstance] = React.useState(); React.useMemo(() => { const cloudDBSchema = new DatabaseSchema({ server_groups: ()=>getNodeListById(pgAdmin.Browser.Nodes['server_group'], props.nodeInfo, props.nodeData), }, { gid: props.nodeInfo['server_group']._id, } ); setCloudDBInstance(cloudDBSchema); }, [props.cloudProvider]); return { /*This is intentional (SonarQube)*/ }} viewHelperProps={{ mode: 'create' }} schema={cloudDBInstance} showFooter={false} isTabView={false} onDataChange={(isChanged, changedData) => { props.setCloudDBDetails(changedData); }} />; } AwsDatabaseDetails.propTypes = { nodeInfo: PropTypes.object, nodeData: PropTypes.object, cloudProvider: PropTypes.string, setCloudDBDetails: PropTypes.func, }; export function validateCloudStep1(cloudDBCred) { let isError = false; if (isEmptyString(cloudDBCred.access_key) || isEmptyString(cloudDBCred.secret_access_key)) { isError = true; } return isError; } export function validateCloudStep2(cloudInstanceDetails, host_ip) { let isError = false; if (isEmptyString(cloudInstanceDetails.name) || isEmptyString(cloudInstanceDetails.db_version) || isEmptyString(cloudInstanceDetails.instance_type) || isEmptyString(cloudInstanceDetails.storage_type)|| isEmptyString(cloudInstanceDetails.storage_size)) { isError = true; } if(cloudInstanceDetails.storage_type == 'io1' && isEmptyString(cloudInstanceDetails.storage_IOPS)) { isError = true; } if (isEmptyString(cloudInstanceDetails.public_ip)) cloudInstanceDetails.public_ip = host_ip; return isError; } export function validateCloudStep3(cloudDBDetails, nodeInfo) { let isError = false; if (isEmptyString(cloudDBDetails.db_name) || isEmptyString(cloudDBDetails.db_username) || isEmptyString(cloudDBDetails.db_password)) { isError = true; } if (isEmptyString(cloudDBDetails.db_port)) cloudDBDetails.db_port = 5432; if (isEmptyString(cloudDBDetails.gid)) cloudDBDetails.gid = nodeInfo['server_group']._id; return isError; } function createData(name, value) { if (typeof(value) == 'boolean') { value = (value === true) ? 'True' : 'False'; } return { name, value }; } export function getAWSSummary(cloud, cloudInstanceDetails, cloudDBDetails) { const rows1 = [ createData(gettext('Cloud'), cloud), createData(gettext('Instance name'), cloudInstanceDetails.name), createData(gettext('Public IP'), cloudInstanceDetails.public_ip), ]; const rows2 = [ createData(gettext('PostgreSQL version'), cloudInstanceDetails.db_version), createData(gettext('Instance type'), cloudInstanceDetails.instance_type), ]; let _storage_type = getStorageType(cloudInstanceDetails); const rows3 = [ createData(gettext('Storage type'), _storage_type[1]), createData(gettext('Allocated storage'), cloudInstanceDetails.storage_size + ' GiB'), ]; if (_storage_type[0] !== undefined) { rows3.push(createData(gettext('Provisioned IOPS'), _storage_type[0])); } const rows4 = [ createData(gettext('Database name'), cloudDBDetails.db_name), createData(gettext('Username'), cloudDBDetails.db_username), createData(gettext('Password'), 'xxxxxxx'), createData(gettext('Port'), cloudDBDetails.db_port), ]; const rows5 = [ createData(gettext('High availability'), cloudInstanceDetails.high_availability), ]; return [rows1, rows2, rows3, rows4, rows5]; } const getStorageType = (cloudInstanceDetails) => { let _storage_type = 'General Purpose SSD (gp2)', _io1; if(cloudInstanceDetails.storage_type == 'gp2'){ _storage_type = 'General Purpose SSD (gp2)';} else if (cloudInstanceDetails.storage_type == 'gp3'){ _storage_type = 'General Purpose SSD (gp3)';} else if(cloudInstanceDetails.storage_type == 'io1') { _storage_type = 'Provisioned IOPS SSD (io1)'; _io1 = cloudInstanceDetails.storage_IOPS; } else if(cloudInstanceDetails.storage_type == 'magnetic') _storage_type = 'Magnetic'; return [_io1, _storage_type]; };