From 448ede53c6a1822c27af5807910c559c091868ae Mon Sep 17 00:00:00 2001 From: Khushboo Vashi Date: Fri, 18 Feb 2022 14:37:05 +0530 Subject: [PATCH] Fixed following issues related to cloud deployment: 1) No options are shown in the instance type. 2) No options for the last 2 types. 3) Unable to change Storage config - size and iops 4) Unable to create an instance when pgAdmin is installed using the installer in Desktop mode 5) Can not create cloud instance with the temporary credentials. 6) Mapped region display name (hardcoded) with region code. --- web/pgacloud/providers/rds.py | 4 +-- web/pgadmin/misc/bgprocess/processes.py | 36 +++++++++++-------- .../misc/cloud/static/js/CloudWizard.jsx | 2 +- .../static/js/cloud_db_details_schema.ui.js | 36 +++++++++++-------- web/pgadmin/misc/cloud/utils/aws_regions.py | 36 +++++++++++++++++++ web/pgadmin/misc/cloud/utils/rds.py | 11 +++--- 6 files changed, 89 insertions(+), 36 deletions(-) create mode 100644 web/pgadmin/misc/cloud/utils/aws_regions.py diff --git a/web/pgacloud/providers/rds.py b/web/pgacloud/providers/rds.py index 3cd82de94..cdae8ea7a 100644 --- a/web/pgacloud/providers/rds.py +++ b/web/pgacloud/providers/rds.py @@ -9,7 +9,6 @@ """ Amazon RDS PostgreSQL provider """ -import configparser import os import time import boto3 @@ -126,7 +125,8 @@ class RdsProvider(AbsProvider): session = boto3.Session( aws_access_key_id=self._access_key, - aws_secret_access_key=self._secret_key + aws_secret_access_key=self._secret_key, + aws_session_token=self._session_token ) self._clients['type'] = session.client(type, region_name=args.region) diff --git a/web/pgadmin/misc/bgprocess/processes.py b/web/pgadmin/misc/bgprocess/processes.py index bc88abbf3..933a1914e 100644 --- a/web/pgadmin/misc/bgprocess/processes.py +++ b/web/pgadmin/misc/bgprocess/processes.py @@ -120,8 +120,13 @@ class BatchProcess(object): if 'id' in kwargs: self._retrieve_process(kwargs['id']) else: + _cmd = kwargs['cmd'] + # Get system's interpreter + if kwargs['cmd'] == 'python': + _cmd = self._get_python_interpreter() + self._create_process( - kwargs['desc'], kwargs['cmd'], kwargs['args'] + kwargs['desc'], _cmd, kwargs['args'] ) def _retrieve_process(self, _id): @@ -246,13 +251,8 @@ class BatchProcess(object): _('The process has already finished and cannot be restarted.') ) - def start(self, cb=None): - self.check_start_end_time() - - executor = file_quote(os.path.join( - os.path.dirname(u_encode(__file__)), 'process_executor.py' - )) - + def _get_python_interpreter(self): + """Get Python Interpreter""" if os.name == 'nt': paths = os.environ['PATH'].split(os.pathsep) @@ -261,14 +261,22 @@ class BatchProcess(object): str(paths) ) - interpreter = self.get_interpreter(paths) + interpreter = self.get_windows_interpreter(paths) else: interpreter = sys.executable - cmd = [ - interpreter if interpreter is not None else 'python', - executor, self.cmd - ] + return interpreter if interpreter else 'python' + + def start(self, cb=None): + self.check_start_end_time() + + executor = file_quote(os.path.join( + os.path.dirname(u_encode(__file__)), 'process_executor.py' + )) + + interpreter = self._get_python_interpreter() + + cmd = [interpreter, executor, self.cmd] cmd.extend(self.args) current_app.logger.info( @@ -383,7 +391,7 @@ class BatchProcess(object): # Explicitly ignoring signals in the child process signal.signal(signal.SIGINT, signal.SIG_IGN) - def get_interpreter(self, paths): + def get_windows_interpreter(self, paths): """ Get interpreter. :param paths: diff --git a/web/pgadmin/misc/cloud/static/js/CloudWizard.jsx b/web/pgadmin/misc/cloud/static/js/CloudWizard.jsx index f27c43323..2db6ec549 100644 --- a/web/pgadmin/misc/cloud/static/js/CloudWizard.jsx +++ b/web/pgadmin/misc/cloud/static/js/CloudWizard.jsx @@ -87,7 +87,7 @@ export default function CloudWizard({ nodeInfo, nodeData }) { var _url = url_for('cloud.get_aws_db_instances') ; if (engine) _url += '?eng_version=' + engine; - if (reload) { + if (reload || options === undefined || options.length == 0) { api.get(_url) .then(res=>{ let data = res.data.data; diff --git a/web/pgadmin/misc/cloud/static/js/cloud_db_details_schema.ui.js b/web/pgadmin/misc/cloud/static/js/cloud_db_details_schema.ui.js index 08cd32437..08487d88a 100644 --- a/web/pgadmin/misc/cloud/static/js/cloud_db_details_schema.ui.js +++ b/web/pgadmin/misc/cloud/static/js/cloud_db_details_schema.ui.js @@ -200,9 +200,9 @@ export class InstanceSchema extends BaseUISchema { deps: ['aws_db_version', 'aws_db_instance_class'], depChange: (state, source)=> { if (source[0] == 'aws_db_instance_class') { - state.reload_instances = false; + return {reload_instances: false}; } else { - state.reload_instances = true; + return {reload_instances: true}; } }, type: (state) => { @@ -215,6 +215,7 @@ export class InstanceSchema extends BaseUISchema { controlProps: { allowClear: false, filter: (options) => { + if (options.length == 0) return; let pattern = 'db.m'; let pattern_1 = 'db.m'; @@ -260,26 +261,31 @@ export class StorageSchema extends BaseUISchema { },{ id: 'aws_storage_size', label: gettext('Allocated storage'), type: 'text', mode: ['create'], noEmpty: true, deps: ['aws_storage_type'], - depChange: (state)=> { - if(state.aws_storage_type === 'io1') { - state.aws_storage_size = 100; - } else if(state.aws_storage_type === 'gp2') { - state.aws_storage_size = 20; - } else { - state.aws_storage_size = 5; - } + depChange: (state, source)=> { + if (source[0] !== 'aws_storage_size') + if(state.aws_storage_type === 'io1') { + return {aws_storage_size: 100}; + } else if(state.aws_storage_type === 'gp2') { + return {aws_storage_size: 20}; + } else { + return {aws_storage_size: 5}; + } }, helpMessage: gettext('Size in GiB.') }, { id: 'aws_storage_IOPS', label: gettext('Provisioned IOPS'), type: 'text', mode: ['create'], visible: (state) => { - if(state.aws_storage_type === 'io1') { - state.aws_storage_IOPS = 3000; - return true; - } + if(state.aws_storage_type === 'io1') return true; return false; - } , deps: ['aws_storage_type'] + } , deps: ['aws_storage_type'], + depChange: (state, source) => { + if (source[0] !== 'aws_storage_IOPS') { + if(state.aws_storage_type === 'io1') { + return {aws_storage_IOPS: 3000}; + } + } + }, }, ]; } diff --git a/web/pgadmin/misc/cloud/utils/aws_regions.py b/web/pgadmin/misc/cloud/utils/aws_regions.py new file mode 100644 index 000000000..785ae9c21 --- /dev/null +++ b/web/pgadmin/misc/cloud/utils/aws_regions.py @@ -0,0 +1,36 @@ +# ########################################################################## +# # +# # pgAdmin 4 - PostgreSQL Tools +# # +# # Copyright (C) 2013 - 2022, The pgAdmin Development Team +# # This software is released under the PostgreSQL Licence +# # +# ########################################################################## +# +# # AWS Regions + + +AWS_REGIONS = { + 'us-gov-east-1': 'AWS GovCloud (US-East)', + 'us-gov-west-1': 'AWS GovCloud (US-West)', + 'ap-east-1': 'Asia Pacific (Hong Kong)', + 'ap-south-': 'Asia Pacific (Mumbai)', + 'ap-northeast-3': 'Asia Pacific (Osaka-Local)', + 'ap-northeast-2': 'Asia Pacific (Seoul)', + 'ap-southeast-1': 'Asia Pacific (Singapore)', + 'ap-southeast-2': 'Asia Pacific (Sydney)', + 'ap-northeast-1': 'Asia Pacific (Tokyo)', + 'ca-central-1': 'Canada (Central)', + 'cn-north-1': 'China (Beijing)', + 'cn-northwest-1': 'China (Ningxia)', + 'eu-central-1': 'EU (Frankfurt)', + 'eu-west-1': 'EU (Ireland)', + 'eu-west-2': 'EU (London)', + 'eu-west-3': 'EU (Paris)', + 'eu-north-1': 'EU (Stockholm)', + 'sa-east-1': 'South America (Sao Paulo)', + 'us-east-1': 'US East (N. Virginia)', + 'us-east-2': 'US East (Ohio)', + 'us-west-1': 'US West (N. California)', + 'us-west-2': 'US West (Oregon)', +} diff --git a/web/pgadmin/misc/cloud/utils/rds.py b/web/pgadmin/misc/cloud/utils/rds.py index bf81d17d4..177e0aaae 100644 --- a/web/pgadmin/misc/cloud/utils/rds.py +++ b/web/pgadmin/misc/cloud/utils/rds.py @@ -13,6 +13,7 @@ import boto3 import pickle from flask import session from boto3.session import Session +from .aws_regions import AWS_REGIONS class RDS(): @@ -163,9 +164,11 @@ def get_aws_regions(): _session = Session() res = _session.get_available_regions('rds') regions = [] + for value in res: - regions.append({ - 'label': value, - 'value': value - }) + if value in AWS_REGIONS: + regions.append({ + 'label': AWS_REGIONS[value] + ' | ' + value, + 'value': value + }) return True, regions