mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-10 07:26:01 -06:00
1) Added SSL support for creating a subscription. Fixes #6201
2) Fixed an issue where the user is not able to create the subscription. Fixes #6230 3) Fixed a couple of issues raised during testing of logical replication.
This commit is contained in:
parent
32197a8405
commit
731ba32e81
@ -43,4 +43,6 @@ Bug fixes
|
||||
| `Issue #6187 <https://redmine.postgresql.org/issues/6187>`_ - Limit the upgrade check to run once per day.
|
||||
| `Issue #6193 <https://redmine.postgresql.org/issues/6193>`_ - Ensure that ERD throws a warning before closing unsaved changes if open in a new tab.
|
||||
| `Issue #6197 <https://redmine.postgresql.org/issues/6197>`_ - Fixed an issue where the ERD image is not properly downloaded.
|
||||
| `Issue #6201 <https://redmine.postgresql.org/issues/6201>`_ - Added SSL support for creating a subscription.
|
||||
| `Issue #6208 <https://redmine.postgresql.org/issues/6208>`_ - Fixed an issue where utility(Backup, Maintenance, ...) jobs are failing when the log level is set to DEBUG.
|
||||
| `Issue #6230 <https://redmine.postgresql.org/issues/6230>`_ - Fixed an issue where the user is not able to create the subscription.
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
},
|
||||
|
||||
}],
|
||||
},
|
||||
],
|
||||
|
@ -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 %}
|
||||
|
@ -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 %}
|
@ -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 %}
|
@ -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 %}
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 %}
|
||||
|
@ -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'])
|
||||
|
@ -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();
|
||||
},
|
||||
|
@ -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 %}
|
||||
|
@ -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 }};
|
||||
|
@ -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 %}
|
||||
|
@ -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();
|
||||
|
@ -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},
|
||||
|
Loading…
Reference in New Issue
Block a user