diff --git a/web/migrations/versions/493cd3e39c0c_.py b/web/migrations/versions/493cd3e39c0c_.py new file mode 100644 index 0000000..fa37750 --- /dev/null +++ b/web/migrations/versions/493cd3e39c0c_.py @@ -0,0 +1,28 @@ + +"""empty message + +Revision ID: 493cd3e39c0c +Revises: 7c56ea250085 +Create Date: 2018-06-18 11:26:33.285037 + +""" +from alembic import op +import sqlalchemy as sa +from pgadmin.model import db + + +# revision identifiers, used by Alembic. +revision = '493cd3e39c0c' +down_revision = '7c56ea250085' +branch_labels = None +depends_on = None + + +def upgrade(): + db.engine.execute( + 'ALTER TABLE server ADD COLUMN connect_timeout INTEGER DEFAULT 0' + ) + + +def downgrade(): + pass diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py index 625d8da..2b9c642 100644 --- a/web/pgadmin/browser/server_groups/servers/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/__init__.py @@ -480,6 +480,7 @@ class ServerNode(PGChildNodeView): 'bgcolor': 'bgcolor', 'fgcolor': 'fgcolor', 'service': 'service', + 'connect_timeout': 'connect_timeout', 'use_ssh_tunnel': 'use_ssh_tunnel', 'tunnel_host': 'tunnel_host', 'tunnel_port': 'tunnel_port', @@ -672,6 +673,8 @@ class ServerNode(PGChildNodeView): 'sslcompression': True if is_ssl and server.sslcompression else False, 'service': server.service if server.service else None, + 'connect_timeout': + server.connect_timeout if server.connect_timeout else 0, 'use_ssh_tunnel': server.use_ssh_tunnel if server.use_ssh_tunnel else 0, 'tunnel_host': server.tunnel_host if server.tunnel_host @@ -755,6 +758,7 @@ class ServerNode(PGChildNodeView): bgcolor=data.get('bgcolor', None), fgcolor=data.get('fgcolor', None), service=data.get('service', None), + connect_timeout=data.get('connect_timeout', 0), use_ssh_tunnel=data.get('use_ssh_tunnel', 0), tunnel_host=data.get('tunnel_host', None), tunnel_port=data.get('tunnel_port', 22), diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js index 0ee3ec0..7005342 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -627,6 +627,7 @@ define('pgadmin.node.server', [ tunnel_identity_file: undefined, tunnel_password: undefined, tunnel_authentication: 0, + connect_timeout: 0, }, // Default values! initialize: function(attrs, args) { @@ -888,6 +889,10 @@ define('pgadmin.node.server', [ id: 'service', label: gettext('Service'), type: 'text', mode: ['properties', 'edit', 'create'], disabled: 'isConnected', group: gettext('Connection'), + },{ + id: 'connect_timeout', label: gettext('Connection timeout (seconds)'), + type: 'int', group: gettext('Advanced'), + mode: ['properties', 'edit', 'create'], disabled: 'isConnected', }], validate: function() { const validateModel = new modelValidation.ModelValidation(this); diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_add_server_with_connect_timeout.py b/web/pgadmin/browser/server_groups/servers/tests/test_add_server_with_connect_timeout.py new file mode 100644 index 0000000..f5c0140 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/tests/test_add_server_with_connect_timeout.py @@ -0,0 +1,47 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2018, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import json + +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils + + +class ServersWithConnectTimeoutAddTestCase(BaseTestGenerator): + """ This class will add the servers under default server group. """ + + scenarios = [ + # Fetch the default url for server object + ( + 'Default Server Node url', dict( + url='/browser/server/obj/' + ) + ) + ] + + def setUp(self): + pass + + def runTest(self): + """ This function will add the server under default server group.""" + url = "{0}{1}/".format(self.url, utils.SERVER_GROUP) + # Add service name in the config + self.server['connect_timeout'] = 5 + response = self.tester.post( + url, + data=json.dumps(self.server), + content_type='html/json' + ) + self.assertEquals(response.status_code, 200) + response_data = json.loads(response.data.decode('utf-8')) + self.server_id = response_data['node']['_id'] + + def tearDown(self): + """This function delete the server from SQLite """ + utils.delete_server_with_api(self.tester, self.server_id) diff --git a/web/pgadmin/model/__init__.py b/web/pgadmin/model/__init__.py index df88116..0c41451 100644 --- a/web/pgadmin/model/__init__.py +++ b/web/pgadmin/model/__init__.py @@ -29,7 +29,7 @@ from flask_sqlalchemy import SQLAlchemy # ########################################################################## -SCHEMA_VERSION = 16 +SCHEMA_VERSION = 17 ########################################################################## # @@ -145,6 +145,7 @@ class Server(db.Model): bgcolor = db.Column(db.Text(10), nullable=True) fgcolor = db.Column(db.Text(10), nullable=True) service = db.Column(db.Text(), nullable=True) + connect_timeout = db.Column(db.Integer(), nullable=False) use_ssh_tunnel = db.Column( db.Integer(), db.CheckConstraint('use_ssh_tunnel >= 0 AND use_ssh_tunnel <= 1'), diff --git a/web/pgadmin/utils/driver/psycopg2/connection.py b/web/pgadmin/utils/driver/psycopg2/connection.py index cfd161a..15f117a 100644 --- a/web/pgadmin/utils/driver/psycopg2/connection.py +++ b/web/pgadmin/utils/driver/psycopg2/connection.py @@ -307,7 +307,8 @@ class Connection(BaseConnection): sslrootcert=get_complete_file_path(manager.sslrootcert), sslcrl=get_complete_file_path(manager.sslcrl), sslcompression=True if manager.sslcompression else False, - service=manager.service + service=manager.service, + connect_timeout=manager.connect_timeout ) # If connection is asynchronous then we will have to wait @@ -1234,7 +1235,8 @@ WHERE sslrootcert=get_complete_file_path(manager.sslrootcert), sslcrl=get_complete_file_path(manager.sslcrl), sslcompression=True if manager.sslcompression else False, - service=manager.service + service=manager.service, + connect_timeout=manager.connect_timeout ) except psycopg2.Error as e: @@ -1519,7 +1521,8 @@ Failed to reset the connection to the server due to following error: sslcrl=get_complete_file_path(self.manager.sslcrl), sslcompression=True if self.manager.sslcompression else False, - service=self.manager.service + service=self.manager.service, + connect_timeout=self.manager.connect_timeout ) # Get the cursor and run the query diff --git a/web/pgadmin/utils/driver/psycopg2/server_manager.py b/web/pgadmin/utils/driver/psycopg2/server_manager.py index 20ce194..a31319d 100644 --- a/web/pgadmin/utils/driver/psycopg2/server_manager.py +++ b/web/pgadmin/utils/driver/psycopg2/server_manager.py @@ -74,6 +74,8 @@ class ServerManager(object): self.sslcrl = server.sslcrl self.sslcompression = True if server.sslcompression else False self.service = server.service + self.connect_timeout = \ + server.connect_timeout if server.connect_timeout else 0 if config.SUPPORT_SSH_TUNNEL: self.use_ssh_tunnel = server.use_ssh_tunnel self.tunnel_host = server.tunnel_host