2023-03-13 04:26:16 -05:00
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2023, 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 GoogleCredSchema extends BaseUISchema {
constructor ( fieldOptions = { } , initValues = { } , eventBus = { } ) {
super ( {
oid : null ,
client _secret _file : undefined ,
... initValues ,
} ) ;
this . fieldOptions = {
... fieldOptions ,
} ;
this . eventBus = eventBus ;
}
get idAttribute ( ) {
return 'oid' ;
}
get baseFields ( ) {
let obj = this ;
return [
{
id : 'client_secret_file' ,
label : gettext ( 'Client secret file' ) ,
type : 'file' ,
2023-03-20 07:52:16 -05:00
helpMessage : gettext ( 'Select a client secrets file containing the client ID, client secret, and other OAuth 2.0 parameters for google authentication. Refer <a href="https://support.google.com/cloud/answer/6158849?hl=en#userconsent&zippy=%2Cuser-consent%2Cpublic-and-internal-applications" target="_blank">link</a> for creating client secret.' ) ,
2023-03-13 04:26:16 -05:00
controlProps : {
dialogType : 'select_file' ,
supportedTypes : [ 'json' ] ,
dialogTitle : 'Select file' ,
} ,
} ,
{
id : 'auth_btn' ,
mode : [ 'create' ] ,
deps : [ 'client_secret_file' ] ,
type : 'button' ,
btnName : gettext ( 'Click here to authenticate yourself to Google' ) ,
helpMessage : gettext ( 'After clicking the button above you will be redirected to the Google authentication page in a new browser tab.' ) ,
disabled : ( state ) => {
return state . client _secret _file ? false : true ;
} ,
depChange : ( ) => {
return { is _authenticating : true } ;
} ,
deferredDepChange : ( state , source ) => {
return new Promise ( ( resolve , reject ) => {
/* button clicked */
if ( source == 'auth_btn' ) {
obj . fieldOptions . authenticateGoogle ( state . client _secret _file )
. then ( ( ) => {
resolve ( ( ) => ( {
2023-03-20 07:52:16 -05:00
is _authenticating : false ,
2023-03-13 04:26:16 -05:00
} ) ) ;
} )
. catch ( ( err ) => {
reject ( err ) ;
} ) ;
}
} ) ;
}
} ,
{
id : 'is_authenticating' ,
visible : false ,
type : '' ,
deps : [ 'auth_btn' ] ,
deferredDepChange : ( state , source ) => {
return new Promise ( ( resolve , reject ) => {
2023-03-20 07:52:16 -05:00
if ( source == 'auth_btn' && state . is _authenticating ) {
2023-03-13 04:26:16 -05:00
obj . fieldOptions . verification _ack ( )
. then ( ( ) => {
resolve ( ) ;
} )
. catch ( ( err ) => {
reject ( err ) ;
} ) ;
}
} ) ;
} ,
} ,
] ; }
}
class GoogleProjectDetailsSchema extends BaseUISchema {
constructor ( fieldOptions = { } , initValues = { } ) {
super ( {
oid : undefined ,
project : '' ,
region : '' ,
availability _zone : '' ,
... initValues ,
} ) ;
this . fieldOptions = {
... fieldOptions ,
} ;
this . initValues = initValues ;
}
get idAttribute ( ) {
return 'oid' ;
}
get baseFields ( ) {
return [
{
id : 'project' ,
label : gettext ( 'Project' ) ,
mode : [ 'create' ] ,
allowClear : false ,
noEmpty : true ,
type : ( ) => {
return {
type : 'select' ,
options : this . fieldOptions . projects
} ;
} ,
} ,
{
id : 'region' ,
label : gettext ( 'Location' ) ,
mode : [ 'create' ] ,
deps : [ 'project' ] ,
noEmpty : true ,
type : ( state ) => {
return {
type : 'select' ,
options : state . project
? ( ) => this . fieldOptions . regions ( state . project )
: [ ] ,
optionsReloadBasis : state . project ,
allowClear : false ,
} ;
} ,
} ,
{
id : 'availability_zone' ,
label : gettext ( 'Availability zone' ) ,
deps : [ 'region' ] ,
allowClear : false ,
noEmpty : true ,
type : ( state ) => {
return {
type : 'select' ,
options : state . region
? ( ) => this . fieldOptions . availabilityZones ( state . region )
: [ ] ,
optionsReloadBasis : state . region ,
} ;
} ,
}
] ;
}
}
class GoogleInstanceSchema extends BaseUISchema {
constructor ( fieldOptions = { } , initValues = { } ) {
super ( {
db _version : '' ,
instance _type : '' ,
storage _size : '' ,
} ) ;
this . fieldOptions = {
... fieldOptions ,
} ;
this . initValues = initValues ;
}
get idAttribute ( ) {
return 'oid' ;
}
get baseFields ( ) {
return [
{
id : 'db_version' ,
label : gettext ( 'Database version' ) ,
deps : [ 'availability_zone' ] ,
type : 'select' ,
noEmpty : true ,
options : this . fieldOptions . dbVersions
} ,
{
id : 'instance_class' ,
label : gettext ( 'Instance class' ) ,
type : 'select' ,
noEmpty : true ,
options : [
{
label : gettext ( 'Shared core' ) ,
value : 'shared' } ,
{
label : gettext ( 'Standard' ) ,
value : 'standard' ,
} ,
{
label : gettext ( 'High Memory' ) ,
value : 'highmem' ,
} ,
] ,
} ,
{
id : 'instance_type' ,
label : gettext ( 'Instance type' ) ,
deps : [ 'instance_class' ] ,
noEmpty : true ,
type : ( state ) => {
return {
type : 'select' ,
allowClear : false ,
options : state . instance _class
? ( ) => this . fieldOptions . instanceTypes ( state . project , state . region , state . instance _class )
: [ ] ,
optionsReloadBasis : state . instance _class
} ;
} ,
}
] ;
}
}
class GoogleStorageSchema extends BaseUISchema {
constructor ( ) {
super ( {
storage _type : 'SSD' ,
} ) ;
}
get baseFields ( ) {
return [
{
id : 'storage_type' ,
label : gettext ( 'Storage type' ) ,
type : 'select' ,
mode : [ 'create' ] ,
noEmpty : true ,
options : [
{ 'label' : gettext ( 'SSD' ) , 'value' : 'PD_SSD' } ,
{ 'label' : gettext ( 'HDD' ) , 'value' : 'PD_HDD' } ,
] ,
} ,
{
id : 'storage_size' ,
label : gettext ( 'Storage capacity' ) ,
2023-03-20 07:52:16 -05:00
type : 'int' ,
2023-03-13 04:26:16 -05:00
mode : [ 'create' ] ,
noEmpty : true ,
deps : [ 'storage_type' ] ,
helpMessage : gettext ( 'Size in GB.' ) ,
}
] ;
}
validate ( data , setErrMsg ) {
if ( data . storage _size && ( data . storage _size < 9 || data . storage _size > 65536 ) ) {
2023-03-20 07:52:16 -05:00
setErrMsg ( 'storage_size' , gettext ( 'Please enter the value between 10 and 65,536.' ) ) ;
2023-03-13 04:26:16 -05:00
return true ;
}
return false ;
}
}
class GoogleNetworkSchema extends BaseUISchema {
constructor ( ) {
super ( ) ;
}
get baseFields ( ) {
return [
{
id : 'public_ips' ,
label : gettext ( 'Public IP range' ) ,
type : 'text' ,
mode : [ 'create' ] ,
noEmpty : true ,
helpMessage : gettext ( 'IP address range for allowed inbound traffic, for example: 127.0.0.1/32. Add multiple IP addresses/ranges separated with commas.'
) ,
} ,
] ;
}
}
class GoogleHighAvailabilitySchema extends BaseUISchema {
constructor ( fieldOptions = { } , initValues = { } ) {
super ( {
oid : undefined ,
high _availability : false ,
... initValues ,
} ) ;
this . fieldOptions = {
... fieldOptions ,
} ;
this . initValues = initValues ;
}
get idAttribute ( ) {
return 'oid' ;
}
get baseFields ( ) {
return [
{
id : 'high_availability' ,
label : gettext ( 'High availability?' ) ,
type : 'switch' ,
helpMessage : gettext ( '' ) ,
} ,
{
id : 'secondary_availability_zone' ,
label : gettext ( 'Secondary availability zone' ) ,
deps : [ 'high_availability' ] ,
allowClear : false ,
disabled : ( state ) => {
if ( ! state . high _availability ) {
state . secondary _availability _zone = '' ;
}
return ! state . high _availability ; } ,
type : ( state ) => {
return {
type : 'select' ,
options : state . region
? ( ) => this . fieldOptions . availabilityZones ( state . region )
: [ ] ,
optionsReloadBasis : state . region ,
} ;
} ,
helpMessage : gettext ( '' ) ,
}
] ;
}
validate ( data , setErrMsg ) {
2023-03-20 07:52:16 -05:00
if ( data . high _availability && ( isEmptyString ( data . secondary _availability _zone ) ) || ( data . secondary _availability _zone == data . availability _zone ) ) {
setErrMsg ( 'secondary_availability_zone' , gettext ( 'Please select Secondary availability zone different than primary.' ) ) ;
2023-03-13 04:26:16 -05:00
return true ;
}
return false ;
}
}
class GoogleDatabaseSchema extends BaseUISchema {
constructor ( fieldOptions = { } , initValues = { } ) {
super ( {
oid : undefined ,
gid : undefined ,
db _username : 'postgres' ,
db _password : '' ,
db _confirm _password : '' ,
... initValues ,
} ) ;
this . fieldOptions = {
... fieldOptions ,
} ;
}
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_username' ,
label : gettext ( 'Admin username' ) ,
type : 'text' ,
mode : [ 'create' ] ,
noEmpty : true ,
disabled : true ,
helpMessage : gettext (
'Admin username for your Google Cloud Sql PostgreSQL instance.' ) ,
} ,
{
id : 'db_password' ,
label : gettext ( 'Password' ) ,
type : 'password' ,
mode : [ 'create' ] ,
noEmpty : true ,
helpMessage : gettext (
'Set a password for the default admin user "postgres".'
) ,
} ,
{
id : 'db_confirm_password' ,
label : gettext ( 'Confirm password' ) ,
type : 'password' ,
mode : [ 'create' ] ,
noEmpty : true ,
} ,
] ;
}
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 ;
}
return false ;
}
}
class GoogleClusterSchema extends BaseUISchema {
constructor ( fieldOptions = { } , initValues = { } ) {
super ( {
oid : undefined ,
name : '' ,
// Need to initilize child class init values in parent class itself
public _ips : initValues ? . hostIP ,
db _instance _class : undefined ,
high _availability : false ,
... initValues ,
} ) ;
this . fieldOptions = {
... fieldOptions ,
} ;
this . initValues = initValues ;
this . googleProjectDetails = new GoogleProjectDetailsSchema (
{
projects : this . fieldOptions . projects ,
regions : this . fieldOptions . regions ,
availabilityZones : this . fieldOptions . availabilityZones ,
} ,
{ }
) ;
this . googleInstanceDetails = new GoogleInstanceSchema (
{
dbVersions : this . fieldOptions . dbVersions ,
instanceTypes : this . fieldOptions . instanceTypes ,
} ,
{ }
) ;
this . googleStorageDetails = new GoogleStorageSchema (
{ } ,
{ }
) ;
this . googleNetworkDetails = new GoogleNetworkSchema ( { } , { } ) ;
this . googleHighAvailabilityDetails = new GoogleHighAvailabilitySchema (
{
availabilityZones : this . fieldOptions . availabilityZones ,
} ,
{ }
) ;
}
get idAttribute ( ) {
return 'oid' ;
}
get baseFields ( ) {
return [
{
id : 'name' ,
label : gettext ( 'Cluster name' ) ,
type : 'text' ,
mode : [ 'create' ] ,
noEmpty : true ,
} ,
{
type : 'nested-fieldset' ,
label : gettext ( 'Project Details' ) ,
mode : [ 'create' ] ,
schema : this . googleProjectDetails ,
} ,
{
type : 'nested-fieldset' ,
label : gettext ( 'Version & Instance' ) ,
mode : [ 'create' ] ,
schema : this . googleInstanceDetails ,
} ,
{
type : 'nested-fieldset' ,
label : gettext ( 'Storage' ) ,
mode : [ 'create' ] ,
schema : this . googleStorageDetails ,
} ,
{
type : 'nested-fieldset' ,
label : gettext ( 'Network Connectivity' ) ,
mode : [ 'create' ] ,
schema : this . googleNetworkDetails ,
} ,
{
type : 'nested-fieldset' ,
label : gettext ( 'Availability' ) ,
mode : [ 'create' ] ,
schema : this . googleHighAvailabilityDetails ,
} ,
] ;
}
2023-03-20 07:52:16 -05:00
validate ( data , setErr ) {
if ( ! isEmptyString ( data . name ) && ( ! /^(?=[a-z])[a-z0-9\-]*$/ . test ( data . name ) || data . name . length > 97 ) ) {
setErr ( 'name' , gettext ( 'Name must only contain lowercase letters, numbers, and hyphens. Start with a letter.' ) ) ;
return true ;
}
return false ;
}
2023-03-13 04:26:16 -05:00
}
2023-03-20 07:52:16 -05:00
export { GoogleCredSchema , GoogleClusterSchema , GoogleDatabaseSchema } ;