mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-01-24 07:16:52 -06:00
352 lines
11 KiB
JavaScript
352 lines
11 KiB
JavaScript
/////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin 4 - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2013 - 2024, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
import gettext from 'sources/gettext';
|
|
import BaseUISchema from 'sources/SchemaView/base_schema.ui';
|
|
import { isEmptyString } from 'sources/validators';
|
|
|
|
|
|
class CloudInstanceDetailsSchema extends BaseUISchema {
|
|
constructor(fieldOptions = {}, initValues = {}) {
|
|
super({
|
|
oid: undefined,
|
|
name: '',
|
|
public_ip: initValues.hostIP,
|
|
high_availability: false,
|
|
...initValues
|
|
});
|
|
|
|
this.fieldOptions = {
|
|
...fieldOptions,
|
|
};
|
|
this.initValues = initValues;
|
|
}
|
|
|
|
get idAttribute() {
|
|
return 'oid';
|
|
}
|
|
|
|
get baseFields() {
|
|
return [
|
|
{
|
|
id: 'name', label: gettext('Instance name'), type: 'text',
|
|
mode: ['create'], noEmpty: true,
|
|
}, {
|
|
id: 'public_ip', label: gettext('Public IP range'), type: 'text',
|
|
mode: ['create'],
|
|
helpMessage: gettext('IP address range for allowed inbound traffic, for example: 127.0.0.1/32. Add multiple IP addresses/ranges separated with commas.'),
|
|
}, {
|
|
type: 'nested-fieldset', label: gettext('Version & Instance'),
|
|
mode: ['create'],
|
|
schema: new InstanceSchema(this.fieldOptions.version,
|
|
this.fieldOptions.instance_type,
|
|
this.fieldOptions.getInstances),
|
|
}, {
|
|
type: 'nested-fieldset', label: gettext('Storage'),
|
|
mode: ['create'],
|
|
schema: new StorageSchema(),
|
|
}, {
|
|
type: 'nested-fieldset', label: gettext('Availability'),
|
|
mode: ['create'],
|
|
schema: new HighAvailablity(),
|
|
},
|
|
];
|
|
}
|
|
}
|
|
|
|
|
|
class CloudDBCredSchema extends BaseUISchema {
|
|
constructor(fieldOptions = {}, initValues = {}) {
|
|
super({
|
|
oid: null,
|
|
region: '',
|
|
access_key: '',
|
|
secret_access_key: '',
|
|
session_token: '',
|
|
is_valid_cred: false,
|
|
...initValues
|
|
});
|
|
|
|
this.fieldOptions = {
|
|
...fieldOptions,
|
|
};
|
|
|
|
}
|
|
|
|
get idAttribute() {
|
|
return 'oid';
|
|
}
|
|
|
|
get baseFields() {
|
|
return [
|
|
{
|
|
id: 'region', label: gettext('Region'),
|
|
type: 'select',
|
|
options: this.fieldOptions.regions,
|
|
controlProps: { allowClear: false },
|
|
noEmpty: true,
|
|
helpMessage: gettext('The cloud instance will be deployed in the selected region.')
|
|
},{
|
|
id: 'access_key', label: gettext('AWS access key'), type: 'text',
|
|
mode: ['create'], noEmpty: true,
|
|
}, {
|
|
id: 'secret_access_key', label: gettext('AWS secret access key'), type: 'password',
|
|
mode: ['create'], noEmpty: true, controlProps: { autoComplete: 'new-password' },
|
|
}, {
|
|
id: 'session_token', label: gettext('AWS session token'), type: 'multiline',
|
|
mode: ['create'], noEmpty: false,
|
|
helpMessage: gettext('Temporary AWS session required session token.')
|
|
}
|
|
];
|
|
}
|
|
}
|
|
|
|
|
|
class DatabaseSchema extends BaseUISchema {
|
|
constructor(fieldOptions = {}, initValues={}) {
|
|
super({
|
|
oid: undefined,
|
|
gid: undefined,
|
|
db_name: '',
|
|
db_username: '',
|
|
db_password: '',
|
|
db_confirm_password: '',
|
|
db_port: 5432,
|
|
...initValues,
|
|
});
|
|
|
|
this.fieldOptions = {
|
|
...fieldOptions,
|
|
};
|
|
|
|
}
|
|
|
|
validate(data, setErrMsg) {
|
|
if(!isEmptyString(data.db_password) && !isEmptyString(data.db_confirm_password)
|
|
&& data.db_password != data.db_confirm_password) {
|
|
setErrMsg('db_confirm_password', gettext('Passwords do not match.'));
|
|
return true;
|
|
}
|
|
if (!isEmptyString(data.db_confirm_password) && data.db_confirm_password.length < 8) {
|
|
setErrMsg('db_confirm_password', gettext('Password must be 8 characters or more.'));
|
|
return true;
|
|
}
|
|
if (data.db_confirm_password.includes('\'') || data.db_confirm_password.includes('"') ||
|
|
data.db_confirm_password.includes('@') || data.db_confirm_password.includes('/')) {
|
|
setErrMsg('db_confirm_password', gettext('Invalid password.'));
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
get idAttribute() {
|
|
return 'oid';
|
|
}
|
|
|
|
get baseFields() {
|
|
return [{
|
|
id: 'gid', label: gettext('pgAdmin server group'), type: 'select',
|
|
options: this.fieldOptions.server_groups,
|
|
mode: ['create'],
|
|
controlProps: { allowClear: false },
|
|
noEmpty: true,
|
|
}, {
|
|
id: 'db_name', label: gettext('Database name'), type: 'text',
|
|
mode: ['create'], noEmpty: true,
|
|
}, {
|
|
id: 'db_username', label: gettext('Username'), type: 'text',
|
|
mode: ['create'], noEmpty: true,
|
|
}, {
|
|
id: 'db_password', label: gettext('Password'), type: 'password',
|
|
mode: ['create'], noEmpty: true, controlProps: { autoComplete: 'new-password' },
|
|
helpMessage: gettext('At least 8 printable ASCII characters. Cannot contain any of the following: / (slash), \'(single quote), "(double quote) and @ (at sign).')
|
|
}, {
|
|
id: 'db_confirm_password', label: gettext('Confirm password'),
|
|
type: 'password',
|
|
mode: ['create'], noEmpty: true,
|
|
}, {
|
|
id: 'db_port', label: gettext('Port'), type: 'text',
|
|
mode: ['create'], noEmpty: true,
|
|
}];
|
|
}
|
|
}
|
|
|
|
|
|
export class InstanceSchema extends BaseUISchema {
|
|
constructor(versionOpts, instanceOpts, getInstances) {
|
|
super({
|
|
db_version: '',
|
|
db_instance_class: 'm',
|
|
instance_type: '',
|
|
reload_instances: true,
|
|
});
|
|
this.versionOpts = versionOpts;
|
|
this.instanceOpts = instanceOpts;
|
|
this.getInstances = getInstances;
|
|
this.instanceData = [];
|
|
}
|
|
|
|
get baseFields() {
|
|
return [{
|
|
id: 'db_version', label: gettext('Database version'),
|
|
type: 'select',
|
|
options: this.versionOpts,
|
|
controlProps: { allowClear: false },
|
|
deps: ['name'],
|
|
noEmpty: true,
|
|
},{
|
|
id: 'db_instance_class', label: gettext('Instance class'),
|
|
type: 'select',
|
|
options: [
|
|
{'label': gettext('Standard classes (includes m classes)'), value: 'm'},
|
|
{'label': gettext('Memory optimized classes (includes r & x classes)'), value: 'x'},
|
|
{'label': gettext('Burstable classes (includes t classes)'), value: 't'},
|
|
], noEmpty: true
|
|
},{
|
|
id: 'instance_type', label: gettext('Instance type'),
|
|
options: this.instanceOpts,
|
|
deps: ['db_version', 'db_instance_class'],
|
|
depChange: (state, source)=> {
|
|
if (source[0] == 'db_instance_class') {
|
|
return {reload_instances: false};
|
|
} else {
|
|
state.instanceData = [];
|
|
return {reload_instances: true};
|
|
}
|
|
},
|
|
type: (state) => {
|
|
return {
|
|
type: 'select',
|
|
options: ()=>this.getInstances(state.db_version,
|
|
state.reload_instances, state.instanceData),
|
|
optionsLoaded: (options) => { state.instanceData = options; },
|
|
optionsReloadBasis: state.db_version + (state.db_instance_class || 'm'),
|
|
controlProps: {
|
|
allowClear: false,
|
|
filter: (options) => {
|
|
if (options.length == 0) return;
|
|
let pattern = 'db.m';
|
|
let pattern_1 = 'db.m';
|
|
|
|
if (state.db_instance_class) {
|
|
pattern = 'db.' + state.db_instance_class;
|
|
pattern_1 = 'db.' + state.db_instance_class;
|
|
}
|
|
if (state.db_instance_class == 'x') {
|
|
pattern_1 = 'db.' + 'r';
|
|
}
|
|
return options.filter((option) => {
|
|
return (option.value.includes(pattern) || option.value.includes(pattern_1));
|
|
});
|
|
},
|
|
}
|
|
};
|
|
},
|
|
}];
|
|
}
|
|
}
|
|
|
|
|
|
export class StorageSchema extends BaseUISchema {
|
|
constructor() {
|
|
super({
|
|
storage_type: 'io1',
|
|
storage_size: 100,
|
|
storage_IOPS: 3000,
|
|
storage_msg: 'Minimum: 20 GiB. Maximum: 16,384 GiB.'
|
|
});
|
|
}
|
|
|
|
get baseFields() {
|
|
return [
|
|
{
|
|
id: 'storage_type', label: gettext('Storage type'), type: 'select',
|
|
mode: ['create'],
|
|
options: [
|
|
{'label': gettext('General Purpose SSD (gp3)'), 'value': 'gp3'},
|
|
{'label': gettext('General Purpose SSD (gp2)'), 'value': 'gp2'},
|
|
{'label': gettext('Provisioned IOPS SSD (io1)'), 'value': 'io1'},
|
|
{'label': gettext('Magnetic'), 'value': 'standard'}
|
|
], noEmpty: true,
|
|
},{
|
|
id: 'storage_size', label: gettext('Allocated storage'), type: 'text',
|
|
mode: ['create'], noEmpty: true, deps: ['storage_type'],
|
|
depChange: (state, source)=> {
|
|
if (source[0] !== 'storage_size')
|
|
if(state.storage_type === 'io1') {
|
|
return {storage_size: 100};
|
|
} else if(state.storage_type === 'gp2' || state.storage_type === 'gp3') {
|
|
return {storage_size: 20};
|
|
} else {
|
|
return {storage_size: 5};
|
|
}
|
|
},
|
|
helpMessage: gettext('Size in GiB.')
|
|
}, {
|
|
id: 'storage_IOPS', label: gettext('Provisioned IOPS'), type: 'text',
|
|
mode: ['create'],
|
|
visible: (state) => {
|
|
return state.storage_type === 'io1';
|
|
} , deps: ['storage_type'],
|
|
depChange: (state, source) => {
|
|
if (source[0] !== 'storage_IOPS') {
|
|
if(state.storage_type === 'io1') {
|
|
return {storage_IOPS: 3000};
|
|
}
|
|
}
|
|
},
|
|
},
|
|
];
|
|
}
|
|
|
|
validate(data, setErrMsg) {
|
|
if(!isEmptyString(data.storage_type) && (data.storage_type === 'gp2' || data.storage_type === 'gp3') && !isEmptyString(data.storage_size) && (data.storage_size < 4 || data.storage_size > 65536)) {
|
|
setErrMsg('storage_size', gettext('Allocated storage should be between 20 - 65536 GiB.'));
|
|
return true;
|
|
}
|
|
if(!isEmptyString(data.storage_type) && data.storage_type === 'io1' && !isEmptyString(data.storage_size) && (data.storage_size < 100 || data.storage_size > 65536)) {
|
|
setErrMsg('storage_size', gettext('Allocated storage should be between 100 - 65536 GiB.'));
|
|
return true;
|
|
}
|
|
if(!isEmptyString(data.storage_type) && data.storage_type === 'standard' && !isEmptyString(data.storage_size) && (data.storage_size < 5 || data.storage_size > 3072)) {
|
|
setErrMsg('storage_size', gettext('Allocated storage should be between 5 - 3072 GiB.'));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export class HighAvailablity extends BaseUISchema {
|
|
constructor() {
|
|
super({
|
|
high_availability: false
|
|
});
|
|
}
|
|
get baseFields() {
|
|
return [
|
|
{
|
|
id: 'high_availability',
|
|
label: gettext('High availability'),
|
|
type: 'switch',
|
|
mode: ['create'],
|
|
helpMessage: gettext(
|
|
'Creates a standby in a different Availability Zone (AZ) to provide data redundancy, eliminate I/O freezes, and minimize latency spikes during system backups.'
|
|
),
|
|
},
|
|
];
|
|
}
|
|
}
|
|
|
|
export {
|
|
CloudInstanceDetailsSchema,
|
|
CloudDBCredSchema,
|
|
DatabaseSchema
|
|
};
|