mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Added support for the infrastructure for on demand access/create the
server connection. The BaseDriver and BaseConnection are two abstract classes, which allows us to replace the existing driver with the currently used. The current implementation supports to connect the PostgreSQL and Postgres Plus Advanced Server using the psycopg2 driver.
This commit is contained in:
@@ -20,6 +20,7 @@ from pgadmin.utils.ajax import make_json_response, \
|
||||
from pgadmin.browser import BrowserPluginModule
|
||||
from pgadmin.utils.menu import MenuItem
|
||||
from pgadmin.settings.settings_model import db, ServerGroup
|
||||
from pgadmin.browser.utils import NodeView
|
||||
|
||||
|
||||
class ServerGroupModule(BrowserPluginModule):
|
||||
@@ -30,13 +31,14 @@ class ServerGroupModule(BrowserPluginModule):
|
||||
"""Return a JSON document listing the server groups for the user"""
|
||||
groups = ServerGroup.query.filter_by(user_id=current_user.id)
|
||||
for group in groups:
|
||||
group = self.generate_browser_node(
|
||||
yield self.generate_browser_node(
|
||||
"%d" % (group.id),
|
||||
None,
|
||||
group.name,
|
||||
"icon-%s" % self.node_type,
|
||||
True)
|
||||
yield group
|
||||
True,
|
||||
self.node_type
|
||||
)
|
||||
|
||||
@property
|
||||
def node_type(self):
|
||||
@@ -46,10 +48,6 @@ class ServerGroupModule(BrowserPluginModule):
|
||||
def script_load(self):
|
||||
return None
|
||||
|
||||
@property
|
||||
def node_path(self):
|
||||
return BrowserPluginModule.browser_url_prefix + self.node_type
|
||||
|
||||
|
||||
class ServerGroupMenuItem(MenuItem):
|
||||
|
||||
@@ -65,29 +63,19 @@ class ServerGroupPluginModule(BrowserPluginModule):
|
||||
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
|
||||
@abstractmethod
|
||||
def get_nodes(self, *arg, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
@property
|
||||
def node_path(self):
|
||||
return BrowserPluginModule.browser_url_prefix + self.node_type
|
||||
|
||||
|
||||
blueprint = ServerGroupModule( __name__, static_url_path='')
|
||||
|
||||
# Initialise the module
|
||||
from pgadmin.browser.utils import NodeView
|
||||
blueprint = ServerGroupModule(__name__, static_url_path='')
|
||||
|
||||
|
||||
class ServerGroupView(NodeView):
|
||||
|
||||
node_type = ServerGroupModule.NODE_TYPE
|
||||
parent_ids = []
|
||||
ids = [{'type':'int', 'id':'gid'}]
|
||||
|
||||
ids = [{'type': 'int', 'id': 'gid'}]
|
||||
|
||||
def list(self):
|
||||
res = []
|
||||
@@ -95,7 +83,6 @@ class ServerGroupView(NodeView):
|
||||
res.append(g)
|
||||
return make_json_response(result=res)
|
||||
|
||||
|
||||
def delete(self, gid):
|
||||
"""Delete a server group node in the settings database"""
|
||||
|
||||
@@ -108,18 +95,22 @@ class ServerGroupView(NodeView):
|
||||
return make_json_response(
|
||||
status=417,
|
||||
success=0,
|
||||
errormsg=gettext('The specified server group could not be found.'))
|
||||
errormsg=gettext(
|
||||
'The specified server group could not be found.'
|
||||
)
|
||||
)
|
||||
else:
|
||||
try:
|
||||
for sg in servergroup:
|
||||
db.session.delete(sg)
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
return make_json_response(status=410, success=0, errormsg=e.message)
|
||||
return make_json_response(
|
||||
status=410, success=0, errormsg=e.message
|
||||
)
|
||||
|
||||
return make_json_response(result=request.form)
|
||||
|
||||
|
||||
def update(self, gid):
|
||||
"""Update the server-group properties"""
|
||||
|
||||
@@ -134,18 +125,22 @@ class ServerGroupView(NodeView):
|
||||
return make_json_response(
|
||||
status=417,
|
||||
success=0,
|
||||
errormsg=gettext('The specified server group could not be found.'))
|
||||
errormsg=gettext(
|
||||
'The specified server group could not be found.'
|
||||
)
|
||||
)
|
||||
else:
|
||||
try:
|
||||
if u'name' in data:
|
||||
servergroup.name = data[u'name']
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
return make_json_response(status=410, success=0, errormsg=e.message)
|
||||
return make_json_response(
|
||||
status=410, success=0, errormsg=e.message
|
||||
)
|
||||
|
||||
return make_json_response(result=request.form)
|
||||
|
||||
|
||||
def properties(self, gid):
|
||||
"""Update the server-group properties"""
|
||||
|
||||
@@ -159,11 +154,15 @@ class ServerGroupView(NodeView):
|
||||
return make_json_response(
|
||||
status=417,
|
||||
success=0,
|
||||
errormsg=gettext('The specified server group could not be found.'))
|
||||
errormsg=gettext(
|
||||
'The specified server group could not be found.'
|
||||
)
|
||||
)
|
||||
else:
|
||||
return ajax_response(response={'id': sg.id, 'name': sg.name},
|
||||
status=200)
|
||||
|
||||
return ajax_response(
|
||||
response={'id': sg.id, 'name': sg.name},
|
||||
status=200
|
||||
)
|
||||
|
||||
def create(self):
|
||||
data = request.form if request.form else json.loads(request.data)
|
||||
@@ -179,14 +178,17 @@ class ServerGroupView(NodeView):
|
||||
data[u'id'] = sg.id
|
||||
data[u'name'] = sg.name
|
||||
|
||||
return jsonify(node=blueprint.generate_browser_node(
|
||||
"%d" % (sg.id),
|
||||
None,
|
||||
sg.name,
|
||||
"icon-%s" % self.node_type,
|
||||
True))
|
||||
return jsonify(
|
||||
node=self.blueprint.generate_browser_node(
|
||||
"%d" % (sg.id),
|
||||
None,
|
||||
sg.name,
|
||||
"icon-%s" % self.node_type,
|
||||
True,
|
||||
self.node_type
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
print 'except'
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
@@ -198,31 +200,18 @@ class ServerGroupView(NodeView):
|
||||
success=0,
|
||||
errormsg=gettext('No server group name was specified'))
|
||||
|
||||
|
||||
def nodes(self, gid):
|
||||
"""Build a list of treeview nodes from the child nodes."""
|
||||
nodes = []
|
||||
for module in blueprint.submodules:
|
||||
nodes.extend(module.get_nodes(server_group=gid))
|
||||
return make_json_response(data=nodes)
|
||||
|
||||
|
||||
def sql(self, gid):
|
||||
return make_json_response(status=422)
|
||||
|
||||
|
||||
def modified_sql(self, gid):
|
||||
return make_json_response(status=422)
|
||||
|
||||
|
||||
def statistics(self, gid):
|
||||
return make_json_response(status=422)
|
||||
|
||||
|
||||
def dependencies(self, gid):
|
||||
return make_json_response(status=422)
|
||||
|
||||
|
||||
def dependents(self, gid):
|
||||
return make_json_response(status=422)
|
||||
|
||||
|
||||
44
web/pgadmin/browser/server_groups/servers/PPAS/__init__.py
Normal file
44
web/pgadmin/browser/server_groups/servers/PPAS/__init__.py
Normal file
@@ -0,0 +1,44 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2015, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
from pgadmin.browser.server_groups.servers import ServerTypeModule
|
||||
from pgadmin.browser.utils import PGChildModule
|
||||
from flask.ext.babel import gettext
|
||||
|
||||
|
||||
class PPASServer(ServerTypeModule, PGChildModule):
|
||||
NODE_TYPE = "ppas"
|
||||
|
||||
@property
|
||||
def node_type(self):
|
||||
return self.NODE_TYPE
|
||||
|
||||
@property
|
||||
def jssnippets(self):
|
||||
return []
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return "PPAS"
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
return "Postgres Plus Advanced Server"
|
||||
|
||||
@property
|
||||
def driver(self):
|
||||
return "psycopg2"
|
||||
|
||||
@property
|
||||
def priority(self):
|
||||
return 1
|
||||
|
||||
def instanceOf(self, ver):
|
||||
return ver.startswith("EnterpriseDB")
|
||||
|
||||
blueprint = PPASServer(__name__, static_url_path='/static')
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 676 B |
@@ -0,0 +1,43 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2015, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
from pgadmin.browser.server_groups.servers import ServerTypeModule
|
||||
from pgadmin.browser.utils import PGChildModule
|
||||
|
||||
|
||||
class PGServer(ServerTypeModule, PGChildModule):
|
||||
NODE_TYPE = "pg"
|
||||
|
||||
@property
|
||||
def node_type(self):
|
||||
return self.NODE_TYPE
|
||||
|
||||
@property
|
||||
def jssnippets(self):
|
||||
return []
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return "PG"
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
return "PostgreSQL"
|
||||
|
||||
@property
|
||||
def driver(self):
|
||||
return "psycopg2"
|
||||
|
||||
@property
|
||||
def priority(self):
|
||||
return 10
|
||||
|
||||
def instanceOf(self, ver):
|
||||
return True
|
||||
|
||||
blueprint = PGServer(__name__, static_url_path='/static')
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 850 B |
@@ -7,17 +7,21 @@
|
||||
#
|
||||
##########################################################################
|
||||
import json
|
||||
from flask import render_template, request, make_response, jsonify
|
||||
from abc import ABCMeta, abstractmethod, abstractproperty
|
||||
from flask import render_template, request, make_response, jsonify, current_app
|
||||
from flask.ext.security import login_required, current_user
|
||||
from pgadmin.settings.settings_model import db, Server, ServerGroup
|
||||
from pgadmin.settings.settings_model import db, Server, ServerGroup, User
|
||||
from pgadmin.utils.menu import MenuItem
|
||||
from pgadmin.utils.ajax import make_json_response, \
|
||||
make_response as ajax_response
|
||||
from pgadmin.browser.utils import NodeView, generate_browser_node
|
||||
make_response as ajax_response, internal_server_error, success_return, \
|
||||
unauthorized, bad_request, precondition_required, forbidden
|
||||
from pgadmin.browser.utils import NodeView
|
||||
import traceback
|
||||
from flask.ext.babel import gettext
|
||||
|
||||
import pgadmin.browser.server_groups as sg
|
||||
from pgadmin.utils.crypto import encrypt, decrypt
|
||||
from pgadmin.browser import BrowserPluginModule
|
||||
from config import PG_DEFAULT_DRIVER
|
||||
|
||||
|
||||
class ServerModule(sg.ServerGroupPluginModule):
|
||||
@@ -35,27 +39,48 @@ class ServerModule(sg.ServerGroupPluginModule):
|
||||
"""
|
||||
return sg.ServerGroupModule.NODE_TYPE
|
||||
|
||||
def get_nodes(self, server_group):
|
||||
def get_nodes(self, gid):
|
||||
"""Return a JSON document listing the server groups for the user"""
|
||||
servers = Server.query.filter_by(user_id=current_user.id,
|
||||
servergroup_id=server_group)
|
||||
servergroup_id=gid)
|
||||
|
||||
from pgadmin.utils.driver import get_driver
|
||||
driver = get_driver(PG_DEFAULT_DRIVER)
|
||||
|
||||
# TODO: Move this JSON generation to a Server method
|
||||
for server in servers:
|
||||
node = generate_browser_node(
|
||||
"%d" % (server.id),
|
||||
"%d" % server_group,
|
||||
server.name,
|
||||
"icon-%s-not-connected" % self.NODE_TYPE,
|
||||
True,
|
||||
self.NODE_TYPE)
|
||||
manager = driver.connection_manager(server.id)
|
||||
conn = manager.connection()
|
||||
module = getattr(manager, "module", None)
|
||||
connected = conn.connected()
|
||||
|
||||
yield node
|
||||
yield self.generate_browser_node(
|
||||
"%d" % (server.id),
|
||||
"%d" % gid,
|
||||
server.name,
|
||||
"icon-server-not-connected" if not connected else
|
||||
"icon-{0}".format(module.NODE_TYPE),
|
||||
True,
|
||||
self.NODE_TYPE,
|
||||
connected=connected,
|
||||
server_type=module.type if module is not None else "PG"
|
||||
)
|
||||
|
||||
@property
|
||||
def jssnippets(self):
|
||||
return []
|
||||
|
||||
@property
|
||||
def csssnippets(self):
|
||||
"""
|
||||
Returns a snippet of css to include in the page
|
||||
"""
|
||||
snippets = [render_template("css/servers.css")]
|
||||
|
||||
for submodule in self.submodules:
|
||||
snippets.extend(submodule.csssnippets)
|
||||
|
||||
return snippets
|
||||
|
||||
|
||||
class ServerMenuItem(MenuItem):
|
||||
def __init__(self, **kwargs):
|
||||
@@ -66,8 +91,83 @@ class ServerMenuItem(MenuItem):
|
||||
blueprint = ServerModule(__name__)
|
||||
|
||||
|
||||
class ServerTypeModule(BrowserPluginModule):
|
||||
"""
|
||||
Base class for different server types.
|
||||
"""
|
||||
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
@abstractproperty
|
||||
def type(self):
|
||||
pass
|
||||
|
||||
@abstractproperty
|
||||
def description(self):
|
||||
pass
|
||||
|
||||
@abstractproperty
|
||||
def priority(self):
|
||||
pass
|
||||
|
||||
def get_nodes(self, manager=None, sid=None):
|
||||
assert(sid is not None)
|
||||
|
||||
nodes = []
|
||||
|
||||
for module in self.submodules:
|
||||
if isinstance(module, PGChildModule):
|
||||
if manager and module.BackendSupported(manager):
|
||||
nodes.extend(module.get_nodes(sid=sid, manager=manager))
|
||||
else:
|
||||
nodes.extend(module.get_nodes(sid=sid))
|
||||
|
||||
return nodes
|
||||
|
||||
@abstractmethod
|
||||
def instanceOf(self, version):
|
||||
pass
|
||||
|
||||
def __str__(self):
|
||||
return "Type: {0},Description:{1}".format(self.type, self.description)
|
||||
|
||||
@property
|
||||
def csssnippets(self):
|
||||
"""
|
||||
Returns a snippet of css to include in the page
|
||||
"""
|
||||
snippets = [
|
||||
render_template(
|
||||
"css/node.css",
|
||||
node_type=self.node_type
|
||||
)
|
||||
]
|
||||
|
||||
for submodule in self.submodules:
|
||||
snippets.extend(submodule.csssnippets)
|
||||
|
||||
return snippets
|
||||
|
||||
def get_own_javascripts(self):
|
||||
scripts = []
|
||||
|
||||
for module in self.submodules:
|
||||
scripts.extend(module.get_own_javascripts())
|
||||
|
||||
return scripts
|
||||
|
||||
@property
|
||||
def script_load(self):
|
||||
"""
|
||||
Load the module script for all server types, when a server node is
|
||||
initialized.
|
||||
"""
|
||||
return ServerTypeModule.NODE_TYPE
|
||||
|
||||
|
||||
class ServerNode(NodeView):
|
||||
node_type = ServerModule.NODE_TYPE
|
||||
|
||||
parent_ids = [{'type': 'int', 'id': 'gid'}]
|
||||
ids = [{'type': 'int', 'id': 'sid'}]
|
||||
operations = dict({
|
||||
@@ -80,7 +180,9 @@ class ServerNode(NodeView):
|
||||
'stats': [{'get': 'statistics'}],
|
||||
'deps': [{'get': 'dependencies', 'post': 'dependents'}],
|
||||
'module.js': [{}, {}, {'get': 'module_js'}],
|
||||
'connect': [{'get': 'connect_status', 'post': 'connect', 'delete': 'disconnect'}]
|
||||
'connect': [{
|
||||
'get': 'connect_status', 'post': 'connect', 'delete': 'disconnect'
|
||||
}]
|
||||
})
|
||||
|
||||
def list(self, gid):
|
||||
@@ -89,20 +191,32 @@ class ServerNode(NodeView):
|
||||
servers = Server.query.filter_by(user_id=current_user.id,
|
||||
servergroup_id=gid)
|
||||
|
||||
from pgadmin.utils.driver import get_driver
|
||||
driver = get_driver(PG_DEFAULT_DRIVER)
|
||||
|
||||
for server in servers:
|
||||
manager = driver.connection_manager(server.id)
|
||||
conn = manager.connection()
|
||||
module = getattr(manager, "module", None)
|
||||
|
||||
connected = conn.connected()
|
||||
res.append(
|
||||
generate_browser_node(
|
||||
"%s" % server.id,
|
||||
"%s" % gid,
|
||||
self.blueprint.generate_browser_node(
|
||||
"%d" % (server.id),
|
||||
"%d" % gid,
|
||||
server.name,
|
||||
"icon-%s-not-connected" % ServerModule.NODE_TYPE,
|
||||
"icon-server-not-connected" if not connected else
|
||||
"icon-{0}".format(module.NODE_TYPE),
|
||||
True,
|
||||
ServerModule.NODE_TYPE)
|
||||
)
|
||||
self.node_type,
|
||||
connected=connected,
|
||||
server_type=module.type if module is not None else 'PG'
|
||||
)
|
||||
)
|
||||
return make_json_response(result=res)
|
||||
|
||||
def delete(self, gid, sid):
|
||||
"""Delete a server node in the settings database"""
|
||||
"""Delete a server node in the settings database."""
|
||||
servers = Server.query.filter_by(user_id=current_user.id, id=sid)
|
||||
|
||||
# TODO:: A server, which is connected, can not be deleted
|
||||
@@ -130,7 +244,8 @@ class ServerNode(NodeView):
|
||||
|
||||
def update(self, gid, sid):
|
||||
"""Update the server settings"""
|
||||
server = Server.query.filter_by(user_id=current_user.id, id=sid).first()
|
||||
server = Server.query.filter_by(
|
||||
user_id=current_user.id, id=sid).first()
|
||||
|
||||
if server is None:
|
||||
return make_json_response(
|
||||
@@ -138,9 +253,8 @@ class ServerNode(NodeView):
|
||||
errormsg=gettext("Couldn't find the given server.")
|
||||
)
|
||||
|
||||
# TODO::
|
||||
# Not all parameters can be modified, while the server is connected
|
||||
possible_args = {
|
||||
# Not all parameters can be modified, while the server is connected
|
||||
config_param_map = {
|
||||
'name': 'name',
|
||||
'host': 'host',
|
||||
'port': 'port',
|
||||
@@ -148,21 +262,49 @@ class ServerNode(NodeView):
|
||||
'username': 'username',
|
||||
'sslmode': 'sslmode',
|
||||
'gid': 'servergroup_id',
|
||||
'comment': 'comment'
|
||||
'comment': 'comment',
|
||||
'role': 'role'
|
||||
}
|
||||
|
||||
disp_lbl = {
|
||||
'name': gettext('name'),
|
||||
'host': gettext('Host name/address'),
|
||||
'port': gettext('Port'),
|
||||
'db': gettext('Maintenance database'),
|
||||
'username': gettext('Username'),
|
||||
'sslmode': gettext('SSL Mode'),
|
||||
'comment': gettext('Comments'),
|
||||
'role': gettext('Role')
|
||||
}
|
||||
|
||||
idx = 0
|
||||
data = request.form if request.form else json.loads(request.data)
|
||||
|
||||
for arg in possible_args:
|
||||
from pgadmin.utils.driver import get_driver
|
||||
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
|
||||
conn = manager.connection()
|
||||
not_allowed = {}
|
||||
|
||||
if conn.connected():
|
||||
for arg in {
|
||||
'host', 'port', 'db', 'username', 'sslmode', 'role'
|
||||
}:
|
||||
if arg in data:
|
||||
return forbidden(
|
||||
errormsg=gettext(
|
||||
"'{0}' is not allowed to modify, when server is connected."
|
||||
).format(disp_lbl[arg])
|
||||
)
|
||||
|
||||
for arg in config_param_map:
|
||||
if arg in data:
|
||||
setattr(server, possible_args[arg], data[arg])
|
||||
setattr(server, config_param_map[arg], data[arg])
|
||||
idx += 1
|
||||
|
||||
if idx == 0:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext('No parameters were chagned!')
|
||||
errormsg=gettext('No parameters were changed!')
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -173,11 +315,14 @@ class ServerNode(NodeView):
|
||||
errormsg=e.message
|
||||
)
|
||||
|
||||
manager.update(server)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
data={
|
||||
'id': server.id,
|
||||
'gid': server.servergroup_id
|
||||
'gid': server.servergroup_id,
|
||||
'icon': 'icon-server-not-connected'
|
||||
}
|
||||
)
|
||||
|
||||
@@ -198,6 +343,14 @@ class ServerNode(NodeView):
|
||||
id=server.servergroup_id
|
||||
).first()
|
||||
|
||||
from pgadmin.utils.driver import get_driver
|
||||
driver = get_driver(PG_DEFAULT_DRIVER)
|
||||
|
||||
manager = driver.connection_manager(sid)
|
||||
conn = manager.connection()
|
||||
connected = conn.connected()
|
||||
module = getattr(manager, 'module', None)
|
||||
|
||||
return ajax_response(
|
||||
response={
|
||||
'id': server.id,
|
||||
@@ -209,9 +362,10 @@ class ServerNode(NodeView):
|
||||
'gid': server.servergroup_id,
|
||||
'group-name': sg.name,
|
||||
'comment': server.comment,
|
||||
# TODO:: Make sure - we do have correct values here
|
||||
'connected': True,
|
||||
'version': 'PostgreSQL 9.3 (linux-x64)'
|
||||
'role': server.role,
|
||||
'connected': connected,
|
||||
'version': manager.ver,
|
||||
'server_type': module.type if module is not None else 'PG'
|
||||
}
|
||||
)
|
||||
|
||||
@@ -223,7 +377,8 @@ class ServerNode(NodeView):
|
||||
u'port',
|
||||
u'db',
|
||||
u'username',
|
||||
u'sslmode'
|
||||
u'sslmode',
|
||||
u'role'
|
||||
]
|
||||
|
||||
data = request.form if request.form else json.loads(request.data)
|
||||
@@ -247,19 +402,25 @@ class ServerNode(NodeView):
|
||||
port=data[u'port'],
|
||||
maintenance_db=data[u'db'],
|
||||
username=data[u'username'],
|
||||
ssl_mode=data['sslmode'],
|
||||
comment=data['comment'] if 'comment' in data else None
|
||||
ssl_mode=data[u'sslmode'],
|
||||
comment=data[u'comment'] if u'comment' in data else None,
|
||||
role=data[u'role'] if u'role' in data else None
|
||||
)
|
||||
db.session.add(server)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify(node=generate_browser_node(
|
||||
'%s' % server.id,
|
||||
'%s' % gid,
|
||||
'%s' % server.name,
|
||||
"icon-{0}-not-connected".format(ServerModule.NODE_TYPE),
|
||||
True,
|
||||
ServerModule.NODE_TYPE))
|
||||
return jsonify(
|
||||
node=self.blueprint.generate_browser_node(
|
||||
"%d" % (server.id),
|
||||
"%d" % gid,
|
||||
server.name,
|
||||
"icon-server-not-connected",
|
||||
True,
|
||||
self.node_type,
|
||||
connected=False,
|
||||
server_type='PG' # Default server type
|
||||
)
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return make_json_response(
|
||||
@@ -270,12 +431,27 @@ class ServerNode(NodeView):
|
||||
|
||||
def nodes(self, gid, sid):
|
||||
"""Build a list of treeview nodes from the child nodes."""
|
||||
from pgadmin.utils.driver import get_driver
|
||||
|
||||
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
|
||||
conn = manager.connection()
|
||||
|
||||
if not conn.connected():
|
||||
return precondition_required(
|
||||
gettext(
|
||||
"Please make a connection to the server first!"
|
||||
)
|
||||
)
|
||||
|
||||
nodes = []
|
||||
# TODO::
|
||||
# We can have nodes for the server object, only when
|
||||
# the server is connected at the moment.
|
||||
for module in blueprint.submodules:
|
||||
nodes.extend(module.get_nodes(server=sid))
|
||||
|
||||
# We will rely on individual server type modules to generate nodes for
|
||||
# them selves.
|
||||
module = getattr(manager, 'module', None)
|
||||
|
||||
if module:
|
||||
nodes.extend(module.get_nodes(sid=sid, manager=manager))
|
||||
|
||||
return make_json_response(data=nodes)
|
||||
|
||||
def sql(self, gid, sid):
|
||||
@@ -299,9 +475,180 @@ class ServerNode(NodeView):
|
||||
Override this property for your own logic.
|
||||
"""
|
||||
return make_response(
|
||||
render_template("servers/servers.js"),
|
||||
render_template(
|
||||
"servers/servers.js",
|
||||
server_types=sorted(
|
||||
[
|
||||
m for m in self.blueprint.submodules
|
||||
if isinstance(m, ServerTypeModule)
|
||||
],
|
||||
key=lambda x: x.priority
|
||||
),
|
||||
_=gettext
|
||||
),
|
||||
200, {'Content-Type': 'application/x-javascript'}
|
||||
)
|
||||
|
||||
def connect_status(self, gid, sid):
|
||||
"""Check and return the connection status."""
|
||||
from pgadmin.utils.driver import get_driver
|
||||
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
|
||||
conn = manager.get_connection()
|
||||
|
||||
return make_json_response(data={'connected': conn.connected()})
|
||||
|
||||
def connect(self, gid, sid):
|
||||
"""
|
||||
Connect the Server and return the connection object.
|
||||
Verification Process before Connection:
|
||||
Verify requested server.
|
||||
|
||||
Check the server password is already been stored in the
|
||||
database or not.
|
||||
If Yes, connect the server and return connection.
|
||||
If No, Raise HTTP error and ask for the password.
|
||||
|
||||
In case of 'Save Password' request from user, excrypted Pasword
|
||||
will be stored in the respected server database and
|
||||
establish the connection OR just connect the server and do not
|
||||
store the password.
|
||||
"""
|
||||
current_app.logger.info(
|
||||
'Connection Request for server#{0}'.format(sid)
|
||||
)
|
||||
|
||||
# Fetch Server Details
|
||||
server = Server.query.filter_by(id=sid).first()
|
||||
if server is None:
|
||||
return bad_request(gettext("Server Not Found."))
|
||||
|
||||
# Fetch User Details.
|
||||
user = User.query.filter_by(id=current_user.id).first()
|
||||
if user is None:
|
||||
return unauthorized(gettext("Unauthorized Request."))
|
||||
|
||||
data = request.form if request.form else json.loads(request.data) if \
|
||||
request.data else {}
|
||||
|
||||
password = None
|
||||
save_password = False
|
||||
|
||||
if 'password' not in data:
|
||||
if server.password is None:
|
||||
# Return the password template in case password is not
|
||||
# provided, or password has not been saved earlier.
|
||||
return make_json_response(
|
||||
success=0,
|
||||
status=428,
|
||||
result=render_template(
|
||||
'servers/password.html',
|
||||
server_label=server.name,
|
||||
username=server.username,
|
||||
_=gettext
|
||||
)
|
||||
)
|
||||
else:
|
||||
password = data['password'] if 'password' in data else None
|
||||
save_password = \
|
||||
data['save_password'] if password and \
|
||||
'save_password' in data else False
|
||||
|
||||
# Encrypt the password before saving with user's login password key.
|
||||
try:
|
||||
password = encrypt(password, user.password) \
|
||||
if password is not None else server.password
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=e.message)
|
||||
|
||||
# Connect the Server
|
||||
from pgadmin.utils.driver import get_driver
|
||||
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
|
||||
conn = manager.connection()
|
||||
|
||||
try:
|
||||
status, errmsg = conn.connect(
|
||||
password=password,
|
||||
modules=[
|
||||
m for m in self.blueprint.submodules
|
||||
if isinstance(m, ServerTypeModule)
|
||||
]
|
||||
)
|
||||
except Exception as e:
|
||||
# TODO::
|
||||
# Ask the password again (if existing password couldn't be
|
||||
# descrypted)
|
||||
return internal_server_error(errormsg=e.message)
|
||||
|
||||
if not status:
|
||||
current_app.logger.error(
|
||||
"Could not connected to server(#{0}) - '{1}'.\nError: {2}".format(
|
||||
server.id, server.name, errmsg
|
||||
)
|
||||
)
|
||||
|
||||
return make_json_response(
|
||||
success=0,
|
||||
status=401,
|
||||
result=render_template(
|
||||
'servers/password.html',
|
||||
server_label=server.name,
|
||||
username=server.username,
|
||||
errmsg=errmsg,
|
||||
_=gettext
|
||||
)
|
||||
)
|
||||
else:
|
||||
if save_password:
|
||||
try:
|
||||
# Save the encrypted password using the user's login
|
||||
# password key.
|
||||
setattr(server, 'password', password)
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
# Release Connection
|
||||
manager.release(database=server.maintenance_db)
|
||||
conn = None
|
||||
|
||||
return internal_server_error(errormsg=e.message)
|
||||
|
||||
current_app.logger.info('Connection Established for server: \
|
||||
%s - %s' % (server.id, server.name))
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Server Connected."),
|
||||
data={
|
||||
'icon': 'icon-{0}'.format(
|
||||
manager.module.NODE_TYPE
|
||||
),
|
||||
'connected': True
|
||||
}
|
||||
)
|
||||
|
||||
def disconnect(self, gid, sid):
|
||||
"""Disconnect the Server."""
|
||||
|
||||
server = Server.query.filter_by(id=sid).first()
|
||||
if server is None:
|
||||
return bad_request(gettext("Server Not Found."))
|
||||
|
||||
# Release Connection
|
||||
from pgadmin.utils.driver import get_driver
|
||||
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
|
||||
|
||||
status = manager.release()
|
||||
|
||||
if not status:
|
||||
return unauthorized(gettext("Server Could Not Disconnect."))
|
||||
else:
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Server Disconnected."),
|
||||
data={
|
||||
'icon': 'icon-server-not-connected',
|
||||
'connected': False
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
ServerNode.register_node_view(blueprint)
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.icon-{{node_type}} {
|
||||
background-image: url('{{ url_for('NODE-%s.static' % node_type, filename='img/%s.png' % node_type )}}') !important;
|
||||
background-repeat: no-repeat;
|
||||
align-content: center;
|
||||
vertical-align: middle;
|
||||
height: 1.3em;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
.icon-server {
|
||||
background-image: url('{{ url_for('NODE-server.static', filename='img/server.png') }}') !important;
|
||||
border-radius: 10px
|
||||
}
|
||||
|
||||
.icon-server-not-connected {
|
||||
background-image: url('{{ url_for('NODE-server.static', filename='img/serverbad.png') }}') !important;
|
||||
border-radius: 10px
|
||||
}
|
||||
|
||||
.icon-server-connecting {
|
||||
background-image: url('{{ url_for('browser.static', filename='css/aciTree/image/load-node.gif')}}') !important;
|
||||
background-repeat: no-repeat;
|
||||
align-content: center;
|
||||
vertical-align: middle;
|
||||
height: 1.3em;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<form name="frmPassword" id="frmPassword" style="height: 100%; width: 100%" onsubmit="return false;">
|
||||
<div>{% if errmsg %}
|
||||
<div class="highlight has-error">
|
||||
<div class='control-label'>{{ errmsg }}</div>
|
||||
</div>{% endif %}
|
||||
<div><b>{{ _('Please enter the password for the user \'{0}\' to connect the server - "{1}"').format(username, server_label) }}</b></div>
|
||||
<div style="padding: 5px; height: 1px;"></div>
|
||||
<div style="width: 100%">
|
||||
<span style="width: 25%;display: inline-table;">Password</span>
|
||||
<span style="width: 73%;display: inline-block;">
|
||||
<input style="width:100%" id="password" class="form-control" name="password" type="password">
|
||||
</span>
|
||||
<span style="margin-left: 25%; padding-top: 15px;width: 45%;display: inline-block;">
|
||||
<input id="save_password" name="save_password" type="checkbox"> Save Password
|
||||
</span>
|
||||
</div>
|
||||
<div style="padding: 5px; height: 1px;"></div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -1,6 +1,6 @@
|
||||
define(
|
||||
['jquery', 'underscore', 'pgadmin', 'pgadmin.browser', 'alertify'],
|
||||
function($, _, pgAdmin, pgBrowser, alertify) {
|
||||
['jquery', 'underscore', 'underscore.string', 'pgadmin', 'pgadmin.browser', 'alertify'],
|
||||
function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
|
||||
if (!pgBrowser.Nodes['server']) {
|
||||
pgAdmin.Browser.Nodes['server'] = pgAdmin.Browser.Node.extend({
|
||||
@@ -29,76 +29,99 @@ function($, _, pgAdmin, pgBrowser, alertify) {
|
||||
name: 'drop_server', node: 'server', module: this,
|
||||
applies: ['object', 'context'], callback: 'delete_obj',
|
||||
category: 'drop', priority: 3, label: '{{ _('Drop Server...') }}',
|
||||
icon: 'fa fa-trash'
|
||||
icon: 'fa fa-trash', enable: 'is_not_connected'
|
||||
},{
|
||||
name: 'connect_server', node: 'server', module: this,
|
||||
applies: ['object', 'context'], callback: 'connect_server',
|
||||
category: 'connect', priority: 4, label: '{{ _('Connect Server...') }}',
|
||||
icon: 'fa fa-link', enable : 'is_not_connected'
|
||||
},
|
||||
{
|
||||
name: 'disconnect_server', node: 'server', module: this,
|
||||
applies: ['object', 'context'], callback: 'disconnect_server',
|
||||
category: 'drop', priority: 5, label: '{{ _('Disconnect Server...') }}',
|
||||
icon: 'fa fa-chain-broken', enable : 'is_connected'
|
||||
}]);
|
||||
},
|
||||
is_not_connected: function(node) {
|
||||
return (node && node.connected != true);
|
||||
},
|
||||
is_connected: function(node) {
|
||||
return (node && node.connected == true);
|
||||
},
|
||||
callbacks: {
|
||||
// Add a server
|
||||
create_server: function (item) {
|
||||
var alert = alertify.prompt(
|
||||
'{{ _('Create a server') }}',
|
||||
'{{ _('Enter a name for the new server') }}',
|
||||
'',
|
||||
function(evt, value) {
|
||||
var d = tree.itemData(item);
|
||||
if (d._type != 'server-group') {
|
||||
d = tree.itemData(tree.parent(item));
|
||||
}
|
||||
$.post(
|
||||
"{{ url_for('browser.index') }}server/obj/" + d.refid + '/' + d.id + '/',
|
||||
{ name: value }
|
||||
)
|
||||
.done(function(data) {
|
||||
if (data.success == 0) {
|
||||
report_error(data.errormsg, data.info);
|
||||
} else {
|
||||
var item = {
|
||||
id: data.data.id,
|
||||
label: data.data.name,
|
||||
inode: true,
|
||||
open: false,
|
||||
icon: 'icon-server-not-connected'
|
||||
}
|
||||
tree.append(null, {
|
||||
itemData: item
|
||||
});
|
||||
/* Connect the server */
|
||||
connect_server: function(args){
|
||||
var input = args || {};
|
||||
obj = this,
|
||||
t = pgBrowser.tree,
|
||||
i = input.item || t.selected(),
|
||||
d = i && i.length == 1 ? t.itemData(i) : undefined;
|
||||
|
||||
if (!d)
|
||||
return false;
|
||||
|
||||
connect_to_server(obj, d, t, i);
|
||||
return false;
|
||||
},
|
||||
/* Disconnect the server */
|
||||
disconnect_server: function(args) {
|
||||
var input = args || {};
|
||||
obj = this,
|
||||
t = pgBrowser.tree,
|
||||
i = input.item || t.selected(),
|
||||
d = i && i.length == 1 ? t.itemData(i) : undefined;
|
||||
|
||||
if (!d)
|
||||
return false;
|
||||
|
||||
alertify.confirm(
|
||||
'{{ _('Disconnect the server') }}',
|
||||
S('{{ _('Are you sure you want to disconnect the server - %%s ?') }}').sprintf(d.label).value(),
|
||||
function(evt) {
|
||||
$.ajax({
|
||||
url: obj.generate_url('connect', d, true),
|
||||
type:'DELETE',
|
||||
success: function(res) {
|
||||
if (res.success == 1) {
|
||||
alertify.success("{{ _('" + res.info + "') }}");
|
||||
t.removeIcon(i);
|
||||
d.connected = false;
|
||||
d.icon = 'icon-server-not-connected';
|
||||
t.addIcon(i, {icon: d.icon});
|
||||
t.unload(i);
|
||||
t.setInode(i);
|
||||
}
|
||||
});
|
||||
},
|
||||
null
|
||||
);
|
||||
alert.show();
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
try {
|
||||
var err = $.parseJSON(xhr.responseText);
|
||||
if (err.success == 0) {
|
||||
msg = S('{{ _(' + err.errormsg + ')}}').value();
|
||||
alertify.error("{{ _('" + err.errormsg + "') }}");
|
||||
}
|
||||
} catch (e) {}
|
||||
t.unload(i);
|
||||
}
|
||||
});
|
||||
},
|
||||
function(evt) {
|
||||
return true;
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
/* Connect the server (if not connected), before opening this node */
|
||||
beforeopen: function(o) {
|
||||
o.browser.tree.removeIcon(o.item);
|
||||
if (o.data.connected) {
|
||||
o.browser.tree.addIcon(o.item, {icon: 'icon-server-connected'});
|
||||
} else {
|
||||
o.browser.tree.addIcon(o.item, {icon: 'icon-server-not-connected'});
|
||||
}
|
||||
var data = o.data;
|
||||
|
||||
if(!data || data._type != 'server') {
|
||||
return false;
|
||||
}
|
||||
|
||||
o.browser.tree.addIcon(o.item, {icon: data.icon});
|
||||
if (!data.connected) {
|
||||
alertify.confirm(
|
||||
'{{ _('Connect to server') }}',
|
||||
'{{ _('Do you want to connect the server?') }}',
|
||||
function(evt) {
|
||||
$.post(
|
||||
"{{ url_for('browser.index') }}server/connect/" + data.refid + '/'
|
||||
).done(function(data) {
|
||||
if (data.success == 0) {
|
||||
report_error(data.errormsg, data.info);
|
||||
}
|
||||
}).fail(function() {});
|
||||
return true;
|
||||
},
|
||||
function(evt) {
|
||||
return true;
|
||||
}
|
||||
);
|
||||
connect_to_server(this, data, o.browser.tree, o.item);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -107,40 +130,61 @@ function($, _, pgAdmin, pgBrowser, alertify) {
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
defaults: {
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
sslmode: 'prefer'
|
||||
name: null,
|
||||
sslmode: 'prefer',
|
||||
host: null,
|
||||
port: 5432,
|
||||
db: null,
|
||||
username: null,
|
||||
role: null
|
||||
},
|
||||
schema: [{
|
||||
id: 'id', label: 'ID', type: 'int', group: null,
|
||||
id: 'id', label: '{{ _('ID') }}', type: 'int', group: null,
|
||||
mode: ['properties']
|
||||
},{
|
||||
id: 'name', label:'Name', type: 'text', group: null,
|
||||
id: 'name', label:'{{ _('Name') }}', type: 'text', group: null,
|
||||
mode: ['properties', 'edit', 'create']
|
||||
},{
|
||||
id: 'connected', label:'Connected', type: 'text', group: null,
|
||||
id: 'connected', label:'{{ _('Connected') }}', type: 'text', group: null,
|
||||
mode: ['properties']
|
||||
},{
|
||||
id: 'version', label:'Version', type: 'text', group: null,
|
||||
id: 'version', label:'{{ _('Version') }}', type: 'text', group: null,
|
||||
mode: ['properties'], show: 'isConnected'
|
||||
},{
|
||||
id: 'comment', label:'Comments:', type: 'multiline', group: null,
|
||||
mode: ['properties', 'edit', 'create'], disable: 'notEditMode'
|
||||
id: 'comment', label:'{{ _('Comments:') }}', type: 'multiline', group: null,
|
||||
mode: ['properties', 'edit', 'create'], disabled: 'notEditMode'
|
||||
},{
|
||||
id: 'host', label:'Host Name/Address', type: 'text', group: "Connection",
|
||||
mode: ['properties', 'edit', 'create']
|
||||
id: 'host', label:'{{ _('Host Name/Address') }}', type: 'text', group: "Connection",
|
||||
mode: ['properties', 'edit', 'create'], disabled: 'isConnected'
|
||||
},{
|
||||
id: 'port', label:'Port', type: 'int', group: "Connection",
|
||||
mode: ['properties', 'edit', 'create']
|
||||
id: 'port', label:'{{ _('Port') }}', type: 'int', group: "Connection",
|
||||
mode: ['properties', 'edit', 'create'], disabled: 'isConnected'
|
||||
},{
|
||||
id: 'db', label:'Maintenance Database', type: 'text', group: "Connection",
|
||||
mode: ['properties', 'edit', 'create']
|
||||
id: 'db', label:'{{ _('Maintenance Database') }}', type: 'text', group: "Connection",
|
||||
mode: ['properties', 'edit', 'create'], disabled: 'isConnected'
|
||||
},{
|
||||
id: 'username', label:'User Name', type: 'text', group: "Connection",
|
||||
mode: ['properties', 'edit', 'create']
|
||||
id: 'username', label:'{{ _('User Name') }}', type: 'text', group: "Connection",
|
||||
mode: ['properties', 'edit', 'create'], disabled: 'isConnected'
|
||||
},{
|
||||
id: 'sslmode', label:'SSL Mode', type: 'options', group: "Connection",
|
||||
mode: ['properties', 'edit', 'create'],
|
||||
'options': [{label:'Allow', value:'allow'}, {label: 'Prefer', value:'prefer'}, {label: 'Require', value: 'require'}, {label: 'Disable', value:'disable'}, {label:'Verify-CA', value: 'verify-ca'}, {label:'Verify-Full', value:'verify-full'}]
|
||||
id: 'role', label:'{{ _('Role') }}', type: 'text', group: "Connection",
|
||||
mode: ['properties', 'edit', 'create'], disabled: 'isConnected'
|
||||
},{
|
||||
id: 'sslmode', label:'{{ _('SSL Mode') }}', type: 'options', group: "Connection",
|
||||
mode: ['properties', 'edit', 'create'], disabled: 'isConnected',
|
||||
'options': [
|
||||
{label: 'Allow', value: 'allow'},
|
||||
{label: 'Prefer', value: 'prefer'},
|
||||
{label: 'Require', value: 'require'},
|
||||
{label: 'Disable', value: 'disable'},
|
||||
{label: 'Verify-CA', value: 'verify-ca'},
|
||||
{label: 'Verify-Full', value: 'verify-full'}
|
||||
]
|
||||
},{
|
||||
id: 'server_type', label: '{{ _('Server Type') }}', type: 'options',
|
||||
mode: ['properties'], show: 'isConnected',
|
||||
'options': [{% set cnt = 1 %}{% for server_type in server_types %}{% if cnt != 1 %},{% endif %}
|
||||
{label: '{{ server_type.description }}', value: '{{ server_type.type}}'}{% set cnt = cnt + 1 %}{% endfor %}
|
||||
]
|
||||
}],
|
||||
validate: function(attrs, options) {
|
||||
if (!this.isNew() && 'id' in this.changed) {
|
||||
@@ -151,13 +195,145 @@ function($, _, pgAdmin, pgBrowser, alertify) {
|
||||
}
|
||||
return null;
|
||||
},
|
||||
isConnected: function(mode) {
|
||||
return mode == 'properties' && this.get('connected');
|
||||
isConnected: function(model) {
|
||||
return model.get('connected');
|
||||
}
|
||||
})
|
||||
});
|
||||
function connect_to_server(obj, data, tree, item) {
|
||||
var onFailure = function(xhr, status, error, _model, _data, _tree, _item) {
|
||||
|
||||
tree.setInode(_item);
|
||||
tree.addIcon(_item, {icon: 'icon-server-not-connected'});
|
||||
|
||||
alertify.pgNotifier('error', xhr, error, function(msg) {
|
||||
setTimeout(function() {
|
||||
alertify.dlgServerPass(
|
||||
'{{ _('Connect to Server') }}',
|
||||
msg, _model, _data, _tree, _item
|
||||
).resizeTo();
|
||||
}, 100);
|
||||
});
|
||||
},
|
||||
onSuccess = function(res, model, data, tree, item) {
|
||||
tree.deselect(item);
|
||||
tree.setInode(item);
|
||||
|
||||
if (res && res.data) {
|
||||
if(typeof res.data.connected == 'boolean') {
|
||||
data.connected = res.data.connected;
|
||||
}
|
||||
if (typeof res.data.icon == 'string') {
|
||||
tree.removeIcon(item);
|
||||
data.icon = res.data.icon;
|
||||
tree.addIcon(item, {icon: data.icon});
|
||||
}
|
||||
|
||||
alertify.success(res.info);
|
||||
setTimeout(function() {tree.select(item);}, 10);
|
||||
setTimeout(function() {tree.open(item);}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
// Ask Password and send it back to the connect server
|
||||
if (!alertify.dlgServerPass) {
|
||||
alertify.dialog('dlgServerPass', function factory() {
|
||||
return {
|
||||
main: function(title, message, model, data, tree, item) {
|
||||
this.set('title', title);
|
||||
this.message = message;
|
||||
this.tree = tree;
|
||||
this.nodeData = data;
|
||||
this.nodeItem = item;
|
||||
this.nodeModel = model;
|
||||
},
|
||||
setup:function() {
|
||||
return {
|
||||
buttons:[
|
||||
{
|
||||
text: "{{ _('OK') }}", key: 13, className: "btn btn-primary"
|
||||
},
|
||||
{
|
||||
text: "{{ _('Cancel') }}", className: "btn btn-danger"
|
||||
}
|
||||
],
|
||||
focus: { element: '#password', select: true },
|
||||
options: {
|
||||
modal: 0, resizable: false, maximizable: false, pinnable: false
|
||||
}
|
||||
};
|
||||
},
|
||||
build:function() {},
|
||||
prepare:function() {
|
||||
this.setContent(this.message);
|
||||
},
|
||||
callback: function(closeEvent) {
|
||||
var _sdata = this.nodeData,
|
||||
_tree = this.tree,
|
||||
_item = this.nodeItem,
|
||||
_model = this.nodeModel;
|
||||
|
||||
if (closeEvent.button.text == "{{ _('OK') }}") {
|
||||
|
||||
var _url = _model.generate_url('connect', _sdata, true);
|
||||
|
||||
_tree.setLeaf(_item);
|
||||
_tree.removeIcon(_item);
|
||||
_tree.addIcon(_item, {icon: 'icon-server-connecting'});
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
timeout: 30000,
|
||||
url: _url,
|
||||
data: $('#frmPassword').serialize(),
|
||||
success: function(res) {
|
||||
return onSuccess(
|
||||
res, _model, _sdata, _tree, _item
|
||||
);
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
return onFailure(
|
||||
xhr, status, error, _model, _sdata, _tree, _item
|
||||
);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_tree.setInode(_item);
|
||||
_tree.removeIcon(_item);
|
||||
_tree.addIcon(_item, {icon: 'icon-server-not-connected'});
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
alertify.confirm(
|
||||
'{{ _('Connect to server') }}',
|
||||
'{{ _('Do you want to connect the server?') }}',
|
||||
function(evt) {
|
||||
url = obj.generate_url("connect", data, true);
|
||||
$.post(url)
|
||||
.done(
|
||||
function(res) {
|
||||
if (res.success == 1) {
|
||||
return onSuccess(res, obj, data, tree, item);
|
||||
}
|
||||
})
|
||||
.fail(
|
||||
function(xhr, status, error) {
|
||||
return onFailure(xhr, status, error, obj, data, tree, item);
|
||||
});
|
||||
},
|
||||
notEditMode: function(mode) {
|
||||
return mode != 'edit';
|
||||
}})
|
||||
});
|
||||
function() {});
|
||||
}
|
||||
/* Send PING to indicate that session is alive */
|
||||
function server_status(server_id)
|
||||
{
|
||||
url = "/ping";
|
||||
$.post(url)
|
||||
.done(function(data) { return true})
|
||||
.fail(function(xhr, status, error) { return false})
|
||||
}
|
||||
}
|
||||
|
||||
return pgBrowser.Nodes['server'];
|
||||
|
||||
@@ -29,7 +29,7 @@ function($, _, pgAdmin, Backbone) {
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
defaults: {
|
||||
id: undefined,
|
||||
name: undefined
|
||||
name: null
|
||||
},
|
||||
schema: [
|
||||
{id: 'id', label: 'ID', type: 'int', group: null, mode: ['properties']},
|
||||
|
||||
Reference in New Issue
Block a user