public inbox for [email protected]
help / color / mirror / Atom feedFrom: Pradip Parkale <[email protected]>
To: pgadmin-hackers <[email protected]>
Subject: [pgAdmin][RM6201]:SSL Support in subscription.
Date: Fri, 19 Feb 2021 13:08:12 +0530
Message-ID: <CAJ9T6StZuyKV=1bKc6zuegSXh94Ttn0e98vSraEp2dpqXhnFLw@mail.gmail.com> (raw)
Hi Hackers,
Please find the attached patch for SSL support in the subscription. I have
also fixed the issue raised during the testing of logical replication.
--
Thanks & Regards,
Pradip Parkale
Software Engineer | EnterpriseDB Corporation
Attachments:
[application/octet-stream] RM6201.patch (31.9K, 3-RM6201.patch)
download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py
index 5daef8120..2f22caf57 100644
--- a/web/pgadmin/browser/server_groups/servers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/__init__.py
@@ -244,6 +244,7 @@ class ServerModule(sg.ServerGroupPluginModule):
user=user_info,
in_recovery=in_recovery,
wal_pause=wal_paused,
+ host=server.host,
is_password_saved=bool(server.save_password),
is_tunnel_password_saved=True
if server.tunnel_password is not None else False,
@@ -535,6 +536,7 @@ class ServerNode(PGChildNodeView):
server_type=server_type,
version=manager.version,
db=manager.db,
+ host=server.host,
user=manager.user_info if connected else None,
in_recovery=in_recovery,
wal_pause=wal_paused,
@@ -604,6 +606,7 @@ class ServerNode(PGChildNodeView):
user=manager.user_info if connected else None,
in_recovery=in_recovery,
wal_pause=wal_paused,
+ host=server.host,
is_password_saved=bool(server.save_password),
is_tunnel_password_saved=True
if server.tunnel_password is not None else False,
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
index 720d628be..4fe459717 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
@@ -80,6 +80,7 @@ define('pgadmin.node.publication', [
evnt_update:true,
evnt_truncate:true,
only_table: undefined,
+ publish_via_partition_root: false,
},
// Default values!
@@ -177,6 +178,20 @@ define('pgadmin.node.publication', [
return false;
},
+ },{
+ id: 'publish_via_partition_root', label: gettext('Publish via root?'),
+ type: 'switch', group: gettext('With'),
+ extraToggleClasses: 'pg-el-sm-6',
+ controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
+ controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
+ visible: function(m) {
+ if(!_.isUndefined(m.node_info) && !_.isUndefined(m.node_info.server)
+ && !_.isUndefined(m.node_info.server.version) &&
+ m.node_info.server.version >= 130000)
+ return true;
+ return false;
+ },
+
}],
},
],
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/11_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/11_plus/properties.sql
index 06c953ba7..0bded27d1 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/11_plus/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/11_plus/properties.sql
@@ -2,7 +2,7 @@ SELECT c.oid AS oid, c.pubname AS name,
pubinsert AS evnt_insert, pubupdate AS evnt_update, pubdelete AS evnt_delete, pubtruncate AS evnt_truncate,
puballtables AS all_table,
pga.rolname AS pubowner FROM pg_publication c
-JOIN pg_authid pga ON c.pubowner= pga.oid
+JOIN pg_roles pga ON c.pubowner= pga.oid
{% if pbid %}
WHERE c.oid = {{ pbid }}
{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/create.sql
new file mode 100644
index 000000000..4f574127e
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/create.sql
@@ -0,0 +1,23 @@
+{% if data.evnt_delete or data.evnt_update or data.evnt_truncate %}
+{% set add_comma_after_insert = 'insert' %}
+{% endif %}
+{% if data.evnt_truncate %}
+{% set add_comma_after_delete = 'delete' %}
+{% endif %}
+{% if data.evnt_delete or data.evnt_truncate%}
+{% set add_comma_after_update = 'update' %}
+{% endif %}
+{% if data.publish_via_partition_root%}
+{% set add_comma_after_truncate = 'truncate' %}
+{% endif %}
+{### Create PUBLICATION ###}
+CREATE PUBLICATION {{ conn|qtIdent(data.name) }}
+{% if data.all_table %}
+ FOR ALL TABLES
+{% elif data.pubtable %}
+ FOR TABLE {% if data.only_table%}ONLY {% endif %}{% for pub_table in data.pubtable %}{% if loop.index != 1 %}, {% endif %}{{ pub_table }}{% endfor %}
+
+{% endif %}
+{% if data.evnt_insert or data.evnt_update or data.evnt_delete or data.evnt_truncate %}
+ WITH (publish = '{% if data.evnt_insert %}insert{% if add_comma_after_insert == 'insert' %}, {% endif %}{% endif %}{% if data.evnt_update %}update{% if add_comma_after_update == 'update' %}, {% endif %}{% endif %}{% if data.evnt_delete %}delete{% if add_comma_after_delete == 'delete' %}, {% endif %}{% endif %}{% if data.evnt_truncate %}truncate{% endif %}', publish_via_partition_root = {{ data.publish_via_partition_root|lower }});
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/properties.sql
new file mode 100644
index 000000000..1694577f6
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/properties.sql
@@ -0,0 +1,9 @@
+SELECT c.oid AS oid, c.pubname AS name,
+pubinsert AS evnt_insert, pubupdate AS evnt_update, pubdelete AS evnt_delete, pubtruncate AS evnt_truncate,
+puballtables AS all_table,
+pubviaroot AS publish_via_partition_root,
+pga.rolname AS pubowner FROM pg_publication c
+JOIN pg_roles pga ON c.pubowner= pga.oid
+{% if pbid %}
+ WHERE c.oid = {{ pbid }}
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/update.sql
new file mode 100644
index 000000000..58542ea4b
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/update.sql
@@ -0,0 +1,48 @@
+{% if data.evnt_delete or data.evnt_update or data.evnt_truncate %}
+{% set add_comma_after_insert = 'insert' %}
+{% endif %}
+{% if data.evnt_truncate %}
+{% set add_comma_after_delete = 'delete' %}
+{% endif %}
+{% if data.evnt_delete or data.evnt_truncate%}
+{% set add_comma_after_update = 'update' %}
+{% endif %}
+{### Alter publication owner ###}
+{% if data.pubowner %}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }}
+ OWNER TO {{ data.pubowner }};
+
+{% endif %}
+{### Alter publication event ###}
+{% if (data.evnt_insert is defined and data.evnt_insert != o_data.evnt_insert) or (data.evnt_update is defined and data.evnt_update != o_data.evnt_update) or (data.evnt_delete is defined and data.evnt_delete != o_data.evnt_delete) or (data.evnt_truncate is defined and data.evnt_truncate != o_data.evnt_truncate) %}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }} SET
+ (publish = '{% if data.evnt_insert %}insert{% if add_comma_after_insert == 'insert' %}, {% endif %}{% endif %}{% if data.evnt_update %}update{% if add_comma_after_update == 'update' %}, {% endif %}{% endif %}{% if data.evnt_delete %}delete{% if add_comma_after_delete == 'delete' %}, {% endif %}{% endif %}{% if data.evnt_truncate %}truncate{% endif %}');
+
+{% endif %}
+{### Alter publication partition root ###}
+{% if data.publish_via_partition_root is defined and data.publish_via_partition_root != o_data.publish_via_partition_root%}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }} SET
+ (publish_via_partition_root = {{ data.publish_via_partition_root|lower }});
+
+{% endif %}
+{### Alter drop publication table ###}
+{% if drop_table %}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }}
+ DROP TABLE {% if data.only_table%}ONLY {% endif %}{% for pub_table in drop_table_data %}{% if loop.index != 1 %}, {% endif %}{{ pub_table }}{% endfor %};
+
+{% endif %}
+{### Alter publication table ###}
+{% if add_table %}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }}
+ ADD TABLE {% if data.only_table%}ONLY {% endif %}{% for pub_table in add_table_data %}{% if loop.index != 1 %}, {% endif %}{{ pub_table }}{% endfor %};
+
+{% endif %}
+{### Alter publication name ###}
+{% if data.name != o_data.name %}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }}
+ RENAME TO {{ conn|qtIdent(data.name) }};
+{% endif %}
+
+
+
+
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_all_tables.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_all_tables.sql
index 874cf00eb..d804ea071 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_all_tables.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_all_tables.sql
@@ -3,4 +3,5 @@ FROM information_schema.tables c
WHERE c.table_type = 'BASE TABLE'
AND c.table_schema NOT LIKE 'pg\_%'
AND c.table_schema NOT LIKE 'pgagent'
+ AND c.table_schema NOT LIKE 'sys'
AND c.table_schema NOT IN ('information_schema') ORDER BY 1;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/properties.sql
index 56ac3dac3..8f6edee94 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/properties.sql
@@ -2,7 +2,7 @@ SELECT c.oid AS oid, c.pubname AS name,
pubinsert AS evnt_insert, pubupdate AS evnt_update, pubdelete AS evnt_delete,
puballtables AS all_table,
pga.rolname AS pubowner FROM pg_publication c
-JOIN pg_authid pga ON c.pubowner= pga.oid
+JOIN pg_roles pga ON c.pubowner= pga.oid
{% if pbid %}
where c.oid = {{ pbid }}
{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/__init__.py
index f2e72207d..48cc1a1ad 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/__init__.py
@@ -261,8 +261,14 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
self._PROPERTIES_SQL]), did=did)
status, res = self.conn.execute_dict(sql)
+ # Check for permission denied message
+ if 'permission denied' in res:
+ return internal_server_error(
+ errormsg="Access is revoked for normal users")
+
if not status:
return internal_server_error(errormsg=res)
+
return ajax_response(
response=res['rows'],
status=200
@@ -680,14 +686,21 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
host=connection_details['host'],
database=connection_details['db'],
user=connection_details['username'],
- password=connection_details['password'] if
- connection_details['password'] else None,
+ password=connection_details[
+ 'password'] if 'password' in connection_details else None,
port=connection_details['port'] if
connection_details['port'] else None,
passfile=get_complete_file_path(passfile),
connect_timeout=connection_details['connect_timeout'] if
'connect_timeout' in connection_details and
- connection_details['connect_timeout'] else 0
+ connection_details['connect_timeout'] else 0,
+ sslmode=connection_details['sslmode'],
+ sslcert=get_complete_file_path(connection_details['sslcert']),
+ sslkey=get_complete_file_path(connection_details['sslkey']),
+ sslrootcert=get_complete_file_path(
+ connection_details['sslrootcert']),
+ sslcompression=True if connection_details[
+ 'sslcompression'] else False,
)
# create a cursor
cur = conn.cursor()
@@ -715,7 +728,9 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
url_params = {k: v for k, v in request.args.items()}
required_connection_args = ['host', 'port', 'username', 'db',
- 'connect_timeout', 'passfile']
+ 'connect_timeout', 'passfile', 'sslmode',
+ 'sslcompression', 'sslcert', 'sslkey',
+ 'sslrootcert', 'sslcrl']
if 'oid' in url_params:
status, params = self._fetch_properties(did, url_params['oid'])
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
index 6c1b71521..78b530771 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
@@ -12,6 +12,7 @@ define('pgadmin.node.subscription', [
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
'sources/browser/server_groups/servers/model_validation', 'pgadmin.alertifyjs', 'pgadmin.browser.collection',
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform, modelValidation, Alertify) {
+ var SSL_MODES = ['prefer', 'require', 'verify-ca', 'verify-full'];
// Extend the browser's collection class for subscriptions collection
if (!pgBrowser.Nodes['coll-subscription']) {
@@ -77,7 +78,7 @@ define('pgadmin.node.subscription', [
name: undefined,
subowner: undefined,
pubtable: undefined,
- connect_timeout: undefined,
+ connect_timeout: 10,
pub:[],
enabled:true,
create_slot: true,
@@ -85,7 +86,18 @@ define('pgadmin.node.subscription', [
connect:true,
copy_data_after_refresh:false,
sync:'off',
- refresh_pub: undefined,
+ refresh_pub: false,
+ password: '',
+ sslmode: 'prefer',
+ sslcompression: false,
+ sslcert: '',
+ sslkey: '',
+ sslrootcert: '',
+ sslcrl: '',
+ host: '',
+ hostaddr: '',
+ port: 5432,
+ db: 'postgres',
},
// Default values!
@@ -189,7 +201,7 @@ define('pgadmin.node.subscription', [
id: 'pub', label: gettext('Publication'), type: 'array', select2: { allowClear: true, multiple: true, width: '92%'},
group: gettext('Connection'), mode: ['create', 'edit'], controlsClassName: 'pgadmin-controls pg-el-sm-11 pg-el-12',
deps: ['all_table', 'host', 'port', 'username', 'db', 'password'], disabled: 'isAllConnectionDataEnter',
- helpMessage: gettext('Click the refresh button to get the publications"'),
+ helpMessage: gettext('Click the refresh button to get the publications'),
control: Backform.Select2Control.extend({
defaults: _.extend(Backform.Select2Control.prototype.defaults, {
select2: {
@@ -280,6 +292,91 @@ define('pgadmin.node.subscription', [
},
}),
},
+ {
+ id: 'sslmode', label: gettext('SSL mode'), control: 'select2', group: gettext('SSL'),
+ select2: {
+ allowClear: false,
+ minimumResultsForSearch: Infinity,
+ },
+ mode: ['properties', 'edit', 'create'],
+ 'options': [
+ {label: gettext('Allow'), value: 'allow'},
+ {label: gettext('Prefer'), value: 'prefer'},
+ {label: gettext('Require'), value: 'require'},
+ {label: gettext('Disable'), value: 'disable'},
+ {label: gettext('Verify-CA'), value: 'verify-ca'},
+ {label: gettext('Verify-Full'), value: 'verify-full'},
+ ],
+ },{
+ id: 'sslcert', label: gettext('Client certificate'), type: 'text',
+ group: gettext('SSL'), mode: ['edit', 'create'],
+ disabled: 'isSSL', control: Backform.FileControl,
+ dialog_type: 'select_file', supp_types: ['*'],
+ deps: ['sslmode'],
+ },{
+ id: 'sslkey', label: gettext('Client certificate key'), type: 'text',
+ group: gettext('SSL'), mode: ['edit', 'create'],
+ disabled: 'isSSL', control: Backform.FileControl,
+ dialog_type: 'select_file', supp_types: ['*'],
+ deps: ['sslmode'],
+ },{
+ id: 'sslrootcert', label: gettext('Root certificate'), type: 'text',
+ group: gettext('SSL'), mode: ['edit', 'create'],
+ disabled: 'isSSL', control: Backform.FileControl,
+ dialog_type: 'select_file', supp_types: ['*'],
+ deps: ['sslmode'],
+ },{
+ id: 'sslcrl', label: gettext('Certificate revocation list'), type: 'text',
+ group: gettext('SSL'), mode: ['edit', 'create'],
+ disabled: 'isSSL', control: Backform.FileControl,
+ dialog_type: 'select_file', supp_types: ['*'],
+ deps: ['sslmode'],
+ },{
+ id: 'sslcompression', label: gettext('SSL compression?'), type: 'switch',
+ mode: ['edit', 'create'], group: gettext('SSL'),
+ 'options': {'size': 'mini'},
+ deps: ['sslmode'], disabled: 'isSSL',
+ },{
+ id: 'sslcert', label: gettext('Client certificate'), type: 'text',
+ group: gettext('SSL'), mode: ['properties'],
+ deps: ['sslmode'],
+ visible: function(model) {
+ var sslcert = model.get('sslcert');
+ return !_.isUndefined(sslcert) && !_.isNull(sslcert);
+ },
+ },{
+ id: 'sslkey', label: gettext('Client certificate key'), type: 'text',
+ group: gettext('SSL'), mode: ['properties'],
+ deps: ['sslmode'],
+ visible: function(model) {
+ var sslkey = model.get('sslkey');
+ return !_.isUndefined(sslkey) && !_.isNull(sslkey);
+ },
+ },{
+ id: 'sslrootcert', label: gettext('Root certificate'), type: 'text',
+ group: gettext('SSL'), mode: ['properties'],
+ deps: ['sslmode'],
+ visible: function(model) {
+ var sslrootcert = model.get('sslrootcert');
+ return !_.isUndefined(sslrootcert) && !_.isNull(sslrootcert);
+ },
+ },{
+ id: 'sslcrl', label: gettext('Certificate revocation list'), type: 'text',
+ group: gettext('SSL'), mode: ['properties'],
+ deps: ['sslmode'],
+ visible: function(model) {
+ var sslcrl = model.get('sslcrl');
+ return !_.isUndefined(sslcrl) && !_.isNull(sslcrl);
+ },
+ },{
+ id: 'sslcompression', label: gettext('SSL compression?'), type: 'switch',
+ mode: ['properties'], group: gettext('SSL'),
+ 'options': {'size': 'mini'},
+ deps: ['sslmode'], visible: function(model) {
+ var sslmode = model.get('sslmode');
+ return _.indexOf(SSL_MODES, sslmode) != -1;
+ },
+ },
{
id: 'copy_data_after_refresh', label: gettext('Copy data?'),
type: 'switch', mode: ['edit'],
@@ -298,8 +395,8 @@ define('pgadmin.node.subscription', [
id: 'create_slot', label: gettext('Create slot?'),
type: 'switch', mode: ['create'],
group: gettext('With'),
- disabled: 'isDisable',
- readonly: 'isConnect', deps :['connect'],
+ disabled: 'isSameDB',
+ readonly: 'isConnect', deps :['connect', 'host'],
helpMessage: gettext('Specifies whether the command should create the replication slot on the publisher.'),
},
@@ -358,13 +455,21 @@ define('pgadmin.node.subscription', [
return false;
return true;
},
+ isSameDB:function(m){
+ if (m.attributes['host'] == m.node_info.server.host){
+ setTimeout( function() {
+ m.set('create_slot', false);
+ }, 10);
+ return true;
+ }
+ return false;
+ },
isAllConnectionDataEnter: function(m){
let host = m.get('host'),
db = m.get('db'),
port = m.get('port'),
- username = m.get('username'),
- password = m.get('password');
- if ((!_.isUndefined(host) && host) && (!_.isUndefined(db) && db) && (!_.isUndefined(port) && port) && (!_.isUndefined(username) && username) && (!_.isUndefined(password) && password))
+ username = m.get('username');
+ if ((!_.isUndefined(host) && host) && (!_.isUndefined(db) && db) && (!_.isUndefined(port) && port) && (!_.isUndefined(username) && username))
return false;
return true;
},
@@ -388,8 +493,12 @@ define('pgadmin.node.subscription', [
}
return false;
},
+ isSSL: function(model) {
+ var ssl_mode = model.get('sslmode');
+ return _.indexOf(SSL_MODES, ssl_mode) == -1;
+ },
sessChanged: function() {
- if (_.isEqual(_.omit(this.attributes, ['refresh_pub']), _.omit(this.origSessAttrs, ['refresh_pub'])) && !this.isNew())
+ if (!this.isNew() && _.isUndefined(this.attributes['refresh_pub']))
return false;
return pgBrowser.DataModel.prototype.sessChanged.apply(this);
},
@@ -400,7 +509,8 @@ define('pgadmin.node.subscription', [
validate: function() {
var msg;
this.errorModel.clear();
- var name = this.get('name');
+ var name = this.get('name'),
+ slot_name = this.get('slot_name');
if (_.isUndefined(name) || _.isNull(name) ||
String(name).replace(/^\s+|\s+$/g, '') == '') {
@@ -409,6 +519,14 @@ define('pgadmin.node.subscription', [
return msg;
}
+ if (!_.isUndefined(slot_name) && !_.isNull(slot_name)){
+ if(/^[a-zA-Z0-9_]+$/.test(slot_name) == false){
+ msg = gettext('Replication slot name may only contain lower case letters, numbers, and the underscore character.');
+ this.errorModel.set('name', msg);
+ return msg;
+ }
+ }
+
const validateModel = new modelValidation.ModelValidation(this);
return validateModel.validate();
},
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/create.sql b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/create.sql
index 08c28a1b6..31bf109f5 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/create.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/create.sql
@@ -12,8 +12,8 @@
{% endif %}
CREATE SUBSCRIPTION {{ conn|qtIdent(data.name) }}
-{% if data.host or data.port or data.username or data.password or data.db %}
- CONNECTION '{% if data.host %}host={{data.host}}{% endif %}{% if data.port %} port={{ data.port }}{% endif %}{% if data.username %} user={{ data.username }}{% endif %}{% if data.db %} dbname={{ data.db }}{% endif %}{% if data.connect_timeout %} connect_timeout={{ data.connect_timeout }}{% endif %}{% if data.passfile %} passfile={{ data.passfile }}{% endif %}{% if data.password %} {% if dummy %}password=xxxxxx{% else %}password={{ data.password}}{% endif %}{% endif %}'
+{% if data.host or data.port or data.username or data.password or data.db or data.connect_timeout or data.passfile or data.sslmode or data.sslcompression or data.sslcert or data.sslkey or data.sslrootcert or data.sslcrl%}
+ CONNECTION '{% if data.host %}host={{data.host}}{% endif %}{% if data.port %} port={{ data.port }}{% endif %}{% if data.username %} user={{ data.username }}{% endif %}{% if data.db %} dbname={{ data.db }}{% endif %}{% if data.connect_timeout %} connect_timeout={{ data.connect_timeout }}{% endif %}{% if data.passfile %} passfile={{ data.passfile }}{% endif %}{% if data.password %} {% if dummy %}password=xxxxxx{% else %}password={{ data.password}}{% endif %}{% endif %}{% if data.sslmode %} sslmode={{ data.sslmode }}{% endif %}{% if data.sslcompression %} sslcompression={{ data.sslcompression }}{% endif %}{% if data.sslcert %} sslcert={{ data.sslcert }}{% endif %}{% if data.sslkey %} sslkey={{ data.sslkey }}{% endif %}{% if data.sslrootcert %} sslrootcert={{ data.sslrootcert }}{% endif %}{% if data.sslcrl %} sslcrl={{ data.sslcrl }}{% endif %}'
{% endif %}
{% if data.pub %}
PUBLICATION {% for pub in data.pub %}{% if loop.index != 1 %},{% endif %}{{ conn|qtIdent(pub) }}{% endfor %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
index 266525779..af958fcb2 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
@@ -1,18 +1,24 @@
-SELECT sub.oid AS oid,
- subname AS name,
- subpublications AS pub,
- sub.subsynccommit AS sync,
- subpublications AS cur_pub,
- pga.rolname AS subowner,
- subslotname AS slot_name,
- subenabled AS enabled,
- SPLIT_PART(SPLIT_PART(subconninfo,' port',1), '=',2) AS host,
- SPLIT_PART(SPLIT_PART(subconninfo,'port=',2), ' ',1) AS port,
- SPLIT_PART(SPLIT_PART(subconninfo,'user=',2), ' ',1) AS username,
- SPLIT_PART(SPLIT_PART(subconninfo,'dbname=',2), ' ',1) AS db,
- SPLIT_PART(SPLIT_PART(subconninfo,'connect_timeout=',2), ' ',1) AS connect_timeout,
- SPLIT_PART(SPLIT_PART(subconninfo,'passfile=',2), ' ',1) AS passfile
-FROM pg_subscription sub JOIN pg_authid pga ON sub.subowner= pga.oid
+SELECT sub.oid as oid,
+ subname as name,
+ subpublications as pub,
+ sub.subsynccommit as sync,
+ subpublications as cur_pub,
+ pga.rolname as subowner,
+ subslotname as slot_name,
+ subenabled as enabled,
+ SPLIT_PART(SPLIT_PART(subconninfo,' port',1), '=',2) as host,
+ SPLIT_PART(SPLIT_PART(subconninfo,'port=',2), ' ',1) as port,
+ SPLIT_PART(SPLIT_PART(subconninfo,'user=',2), ' ',1) as username,
+ SPLIT_PART(SPLIT_PART(subconninfo,'dbname=',2), ' ',1) as db,
+ SPLIT_PART(SPLIT_PART(subconninfo,'connect_timeout=',2), ' ',1) as connect_timeout,
+ SPLIT_PART(SPLIT_PART(subconninfo,'passfile=',2), ' ',1) as passfile,
+ SPLIT_PART(SPLIT_PART(subconninfo,'sslmode=',2), ' ',1) as sslmode,
+ SPLIT_PART(SPLIT_PART(subconninfo,'sslcompression=',2), ' ',1) as sslcompression,
+ SPLIT_PART(SPLIT_PART(subconninfo,'sslcert=',2), ' ',1) as sslcert,
+ SPLIT_PART(SPLIT_PART(subconninfo,'sslkey=',2), ' ',1) as sslkey,
+ SPLIT_PART(SPLIT_PART(subconninfo,'sslrootcert=',2), ' ',1) as sslrootcert,
+ SPLIT_PART(SPLIT_PART(subconninfo,'sslcrl=',2), ' ',1) as sslcrl
+FROM pg_subscription sub join pg_roles pga on sub.subowner= pga.oid
WHERE
{% if subid %}
sub.oid = {{ subid }};
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/update.sql b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/update.sql
index f04a00466..04c435a69 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/update.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/update.sql
@@ -47,9 +47,9 @@ ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
{% endif %}
{### Alter subscription connection info ###}
-{% if data.host or data.port or data.username or data.password or data.db or data.connect_timeout or data.passfile %}
+{% if data.host or data.port or data.username or data.password or data.db or data.connect_timeout or data.passfile or data.sslmode or data.sslcompression or data.sslcert or data.sslkey or data.sslrootcert or data.sslcrl %}
ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
- CONNECTION 'host={{ o_data.host}} port={{ o_data.port }} user={{ o_data.username }} dbname={{ o_data.db }}{% if data.connect_timeout %} connect_timeout={{ o_data.connect_timeout }}{% endif %}{% if data.passfile %} passfile={{ o_data.passfile }}{% endif %}{% if data.password %} {% if dummy %}password=xxxxxx{% else %} password={{ data.password}}{% endif %}{% endif %}';
+ CONNECTION 'host={{ o_data.host}} port={{ o_data.port }} user={{ o_data.username }} dbname={{ o_data.db }}{% if data.connect_timeout %} connect_timeout={{ o_data.connect_timeout }}{% endif %}{% if data.passfile %} passfile={{ o_data.passfile }}{% endif %}{% if data.password %} {% if dummy %}password=xxxxxx{% else %} password={{ data.password}}{% endif %}{% endif %}{% if data.sslmode %} sslmode={{ data.sslmode }}{% endif %}{% if data.sslcompression %} sslcompression={{ data.sslcompression }}{% endif %}{% if data.sslcert %} sslcert={{ data.sslcert }}{% endif %}{% if data.sslkey %} sslkey={{ data.sslkey }}{% endif %}{% if data.sslrootcert %} sslrootcert={{ data.sslrootcert }}{% endif %}{% if data.sslcrl %} sslcrl={{ data.sslcrl }}{% endif %}';
{% endif %}
{### Alter subscription name ###}
{% if data.name and data.name != o_data.name %}
diff --git a/web/pgadmin/static/js/browser/server_groups/servers/model_validation.js b/web/pgadmin/static/js/browser/server_groups/servers/model_validation.js
index 2e391b5b6..33d073a6b 100644
--- a/web/pgadmin/static/js/browser/server_groups/servers/model_validation.js
+++ b/web/pgadmin/static/js/browser/server_groups/servers/model_validation.js
@@ -40,15 +40,11 @@ export class ModelValidation {
this.checkForEmpty('username', gettext('Username must be specified.'));
this.checkForEmpty('port', gettext('Port must be specified.'));
if(!_.isUndefined(pub)){
- if (this.model.isNew())
- this.checkForEmpty('password', gettext('Password must be specified.'));
this.checkForEmpty('pub', gettext('Publication must be specified.'));
}
} else {
this.checkForEmpty('db', gettext('Maintenance database must be specified.'));
if(!_.isUndefined(pub)){
- if (this.model.isNew())
- this.checkForEmpty('password', gettext('Password must be specified.'));
this.checkForEmpty('pub', gettext('Publication must be specified.'));
}
this.clearHostAddressAndDbErrors();
diff --git a/web/pgadmin/utils/versioned_template_loader.py b/web/pgadmin/utils/versioned_template_loader.py
index ca4f3146c..c4dcc1528 100644
--- a/web/pgadmin/utils/versioned_template_loader.py
+++ b/web/pgadmin/utils/versioned_template_loader.py
@@ -84,7 +84,8 @@ def get_version_mapping_directories(server_type):
{'name': "default", 'number': 0}
)
- return ({'name': "12_plus", 'number': 120000},
+ return ({'name': "13_plus", 'number': 130000},
+ {'name': "12_plus", 'number': 120000},
{'name': "11_plus", 'number': 110000},
{'name': "10_plus", 'number': 100000},
{'name': "9.6_plus", 'number': 90600},
view thread (4+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [pgAdmin][RM6201]:SSL Support in subscription.
In-Reply-To: <CAJ9T6StZuyKV=1bKc6zuegSXh94Ttn0e98vSraEp2dpqXhnFLw@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox