Allow the connection timeout to be configured on a per-server basis. Fixes #3388
parent
9821e28da5
commit
7a06acb678
Binary file not shown.
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 70 KiB |
|
@ -14,6 +14,7 @@ Features
|
|||
| `Feature #2686 <https://redmine.postgresql.org/issues/2686>`_ - Add an option to auto-complete keywords in upper case
|
||||
| `Feature #3204 <https://redmine.postgresql.org/issues/3204>`_ - Add support for LISTEN/NOTIFY in the query tool
|
||||
| `Feature #3362 <https://redmine.postgresql.org/issues/3362>`_ - Function and procedure support for PG11
|
||||
| `Feature #3388 <https://redmine.postgresql.org/issues/3388>`_ - Allow the connection timeout to be configured on a per-server basis
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
|
|
@ -85,6 +85,7 @@ Use the fields in the *Advanced* tab to configure a connection:
|
|||
* Specify the IP address of the server host in the *Host address* field. Using this field to specify the host IP address may save time by avoiding a DNS lookup on connection, but it may be useful to specify both a host name and address when using Kerberos, GSSAPI, or SSPI authentication methods, as well as for verify-full SSL certificate verification.
|
||||
* Use the *DB restriction* field to provide a SQL restriction that will be used against the pg_database table to limit the databases that you see. For example, you might enter: *live_db test_db* so that only live_db and test_db are shown in the pgAdmin browser. Separate entries with a comma or tab as you type.
|
||||
* Use the *Password File* field to specify the location of a password file (.pgpass). A .pgpass file allows a user to login without providing a password when they connect. For more information, see `Section 33.15 of the Postgres documentation <http://www.postgresql.org/docs/current/static/libpq-pgpass.html>`_.
|
||||
* Use the *Connection timeout* field to specify the maximum wait for connection, in seconds. Zero or not specified means wait indefinitely. It is not recommended to use a timeout of less than 2 seconds.
|
||||
|
||||
*NOTE:* The password file option is only supported when pgAdmin is using libpq v10.0 or later to connect to the server.
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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),
|
||||
|
|
|
@ -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,11 @@ 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',
|
||||
min: 0,
|
||||
}],
|
||||
validate: function() {
|
||||
const validateModel = new modelValidation.ModelValidation(this);
|
||||
|
|
|
@ -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)
|
|
@ -173,8 +173,8 @@ define([
|
|||
id: s.id,
|
||||
label: s.label,
|
||||
type: s.type,
|
||||
min: s.min || undefined,
|
||||
max: s.max || undefined,
|
||||
min: !_.isUndefined(s.min) ? s.min : undefined,
|
||||
max: !_.isUndefined(s.max) ? s.max : undefined,
|
||||
};
|
||||
break;
|
||||
default:
|
||||
|
@ -767,9 +767,9 @@ define([
|
|||
min_value = field.min,
|
||||
max_value = field.max;
|
||||
|
||||
if (min_value && value < min_value) {
|
||||
if (!_.isUndefined(min_value) && value < min_value) {
|
||||
return S(pgAdmin.Browser.messages.MUST_GR_EQ).sprintf(label, min_value).value();
|
||||
} else if (max_value && value > max_value) {
|
||||
} else if (!_.isUndefined(max_value) && value > max_value) {
|
||||
return S(pgAdmin.Browser.messages.MUST_LESS_EQ).sprintf(label, max_value).value();
|
||||
}
|
||||
return null;
|
||||
|
@ -1301,4 +1301,4 @@ define([
|
|||
pgBrowser.Events = _.extend({}, Backbone.Events);
|
||||
|
||||
return pgBrowser;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -334,7 +334,15 @@ def create_backup_job(sid):
|
|||
cmd=utility, args=args
|
||||
)
|
||||
manager.export_password_env(p.id)
|
||||
p.set_env_variables(server)
|
||||
# Check for connection timeout and if it is greater than 0 then
|
||||
# set the environment variable PGCONNECT_TIMEOUT.
|
||||
if manager.connect_timeout > 0:
|
||||
env = dict()
|
||||
env['PGCONNECT_TIMEOUT'] = str(manager.connect_timeout)
|
||||
p.set_env_variables(server, env=env)
|
||||
else:
|
||||
p.set_env_variables(server)
|
||||
|
||||
p.start()
|
||||
jid = p.id
|
||||
except Exception as e:
|
||||
|
@ -499,7 +507,15 @@ def create_backup_objects_job(sid):
|
|||
cmd=utility, args=args
|
||||
)
|
||||
manager.export_password_env(p.id)
|
||||
p.set_env_variables(server)
|
||||
# Check for connection timeout and if it is greater than 0 then
|
||||
# set the environment variable PGCONNECT_TIMEOUT.
|
||||
if manager.connect_timeout > 0:
|
||||
env = dict()
|
||||
env['PGCONNECT_TIMEOUT'] = str(manager.connect_timeout)
|
||||
p.set_env_variables(server, env=env)
|
||||
else:
|
||||
p.set_env_variables(server)
|
||||
|
||||
p.start()
|
||||
jid = p.id
|
||||
except Exception as e:
|
||||
|
|
|
@ -240,7 +240,15 @@ def create_maintenance_job(sid, did):
|
|||
cmd=utility, args=args
|
||||
)
|
||||
manager.export_password_env(p.id)
|
||||
p.set_env_variables(server)
|
||||
# Check for connection timeout and if it is greater than 0 then
|
||||
# set the environment variable PGCONNECT_TIMEOUT.
|
||||
if manager.connect_timeout > 0:
|
||||
env = dict()
|
||||
env['PGCONNECT_TIMEOUT'] = str(manager.connect_timeout)
|
||||
p.set_env_variables(server, env=env)
|
||||
else:
|
||||
p.set_env_variables(server)
|
||||
|
||||
p.start()
|
||||
jid = p.id
|
||||
except Exception as e:
|
||||
|
|
|
@ -342,7 +342,15 @@ def create_restore_job(sid):
|
|||
cmd=utility, args=args
|
||||
)
|
||||
manager.export_password_env(p.id)
|
||||
p.set_env_variables(server)
|
||||
# Check for connection timeout and if it is greater than 0 then
|
||||
# set the environment variable PGCONNECT_TIMEOUT.
|
||||
if manager.connect_timeout > 0:
|
||||
env = dict()
|
||||
env['PGCONNECT_TIMEOUT'] = str(manager.connect_timeout)
|
||||
p.set_env_variables(server, env=env)
|
||||
else:
|
||||
p.set_env_variables(server)
|
||||
|
||||
p.start()
|
||||
jid = p.id
|
||||
except Exception as e:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue