mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 01:18:58 +00:00
Merge pull request #6398 from s0undt3ch/issues/6352-parser-psql-beta-version
Properly parse a PSQL server version, even beta versions
This commit is contained in:
commit
a3dc67c15e
@ -19,6 +19,7 @@ Module to provide Postgres compatibility to salt.
|
||||
|
||||
# Import python libs
|
||||
import datetime
|
||||
import distutils
|
||||
import pipes
|
||||
import logging
|
||||
import csv
|
||||
@ -101,6 +102,18 @@ def version(user=None, host=None, port=None, maintenance_db=None,
|
||||
return line
|
||||
|
||||
|
||||
def _parsed_version(user=None, host=None, port=None, maintenance_db=None,
|
||||
password=None, runas=None):
|
||||
'''
|
||||
Returns the server version properly parsed and int casted for internal use
|
||||
'''
|
||||
|
||||
psql_version = version(
|
||||
user, host, port, maintenance_db, password, runas
|
||||
)
|
||||
return distutils.version.LooseVersion(psql_version).version
|
||||
|
||||
|
||||
def _connection_defaults(user=None, host=None, port=None, maintenance_db=None,
|
||||
password=None):
|
||||
'''
|
||||
@ -209,12 +222,14 @@ def db_list(user=None, host=None, port=None, maintenance_db=None,
|
||||
|
||||
ret = {}
|
||||
|
||||
query = 'SELECT datname as "Name", pga.rolname as "Owner", ' \
|
||||
'pg_encoding_to_char(encoding) as "Encoding", ' \
|
||||
'datcollate as "Collate", datctype as "Ctype", ' \
|
||||
'datacl as "Access privileges", spcname as "Tablespace" ' \
|
||||
'FROM pg_database pgd, pg_roles pga, pg_tablespace pgts ' \
|
||||
'WHERE pga.oid = pgd.datdba AND pgts.oid = pgd.dattablespace'
|
||||
query = (
|
||||
'SELECT datname as "Name", pga.rolname as "Owner", '
|
||||
'pg_encoding_to_char(encoding) as "Encoding", '
|
||||
'datcollate as "Collate", datctype as "Ctype", '
|
||||
'datacl as "Access privileges", spcname as "Tablespace" '
|
||||
'FROM pg_database pgd, pg_roles pga, pg_tablespace pgts '
|
||||
'WHERE pga.oid = pgd.datdba AND pgts.oid = pgd.dattablespace'
|
||||
)
|
||||
|
||||
rows = psql_query(query, runas=runas, host=host, user=user,
|
||||
port=port, maintenance_db=maintenance_db,
|
||||
@ -276,9 +291,9 @@ def db_create(name,
|
||||
# doesn't get thrown by dashes in the name
|
||||
'OWNER': owner and '"{0}"'.format(owner),
|
||||
'TEMPLATE': template,
|
||||
'ENCODING': encoding and '\'{0}\''.format(encoding),
|
||||
'LC_COLLATE': lc_collate and '\'{0}\''.format(lc_collate),
|
||||
'LC_CTYPE': lc_ctype and '\'{0}\''.format(lc_ctype),
|
||||
'ENCODING': encoding and '{0!r}'.format(encoding),
|
||||
'LC_COLLATE': lc_collate and '{0!r}'.format(lc_collate),
|
||||
'LC_CTYPE': lc_ctype and '{0!r}'.format(lc_ctype),
|
||||
'TABLESPACE': tablespace,
|
||||
}
|
||||
with_chunks = []
|
||||
@ -320,8 +335,8 @@ def db_alter(name, user=None, host=None, port=None, maintenance_db=None,
|
||||
queries.append('ALTER DATABASE "{0}" SET TABLESPACE "{1}"'.format(
|
||||
name, tablespace
|
||||
))
|
||||
for Q in queries:
|
||||
cmd = _psql_cmd('-c', Q, user=user, host=host, port=port,
|
||||
for query in queries:
|
||||
cmd = _psql_cmd('-c', query, user=user, host=host, port=port,
|
||||
maintenance_db=maintenance_db, password=password)
|
||||
ret = _run_psql(cmd, runas=runas, password=password, host=host)
|
||||
if ret['retcode'] != 0:
|
||||
@ -362,13 +377,13 @@ def user_list(user=None, host=None, port=None, maintenance_db=None,
|
||||
|
||||
ret = {}
|
||||
|
||||
ver = version(user=user,
|
||||
host=host,
|
||||
port=port,
|
||||
maintenance_db=maintenance_db,
|
||||
password=password,
|
||||
runas=runas).split('.')
|
||||
if len(ver) >= 2 and int(ver[0]) >= 9 and int(ver[1]) >= 1:
|
||||
ver = _parsed_version(user=user,
|
||||
host=host,
|
||||
port=port,
|
||||
maintenance_db=maintenance_db,
|
||||
password=password,
|
||||
runas=runas)
|
||||
if len(ver) >= 2 and ver[0] >= 9 and ver[1] >= 1:
|
||||
query = (
|
||||
'SELECT rolname as "name", rolsuper as "superuser", '
|
||||
'rolinherit as "inherits privileges", '
|
||||
@ -471,25 +486,25 @@ def _role_create(name,
|
||||
# check if role exists
|
||||
if user_exists(name, user, host, port, maintenance_db,
|
||||
password=password, runas=runas):
|
||||
log.info('{0} \'{1}\' already exists'.format(create_type, name,))
|
||||
log.info('{0} {1!r} already exists'.format(create_type, name))
|
||||
return False
|
||||
|
||||
sub_cmd = 'CREATE {0} "{1}" WITH'.format(create_type, name, )
|
||||
sub_cmd = 'CREATE {0} "{1}" WITH'.format(create_type, name)
|
||||
if rolepassword is not None:
|
||||
if encrypted:
|
||||
sub_cmd = '{0} ENCRYPTED'.format(sub_cmd, )
|
||||
sub_cmd = '{0} ENCRYPTED'.format(sub_cmd)
|
||||
escaped_password = rolepassword.replace('\'', '\'\'')
|
||||
sub_cmd = '{0} PASSWORD \'{1}\''.format(sub_cmd, escaped_password)
|
||||
sub_cmd = '{0} PASSWORD {1!r}'.format(sub_cmd, escaped_password)
|
||||
if createdb:
|
||||
sub_cmd = '{0} CREATEDB'.format(sub_cmd, )
|
||||
sub_cmd = '{0} CREATEDB'.format(sub_cmd)
|
||||
if createuser:
|
||||
sub_cmd = '{0} CREATEUSER'.format(sub_cmd, )
|
||||
sub_cmd = '{0} CREATEUSER'.format(sub_cmd)
|
||||
if superuser:
|
||||
sub_cmd = '{0} SUPERUSER'.format(sub_cmd, )
|
||||
sub_cmd = '{0} SUPERUSER'.format(sub_cmd)
|
||||
if replication:
|
||||
sub_cmd = '{0} REPLICATION'.format(sub_cmd, )
|
||||
sub_cmd = '{0} REPLICATION'.format(sub_cmd)
|
||||
if groups:
|
||||
sub_cmd = '{0} IN GROUP {1}'.format(sub_cmd, groups, )
|
||||
sub_cmd = '{0} IN GROUP {1}'.format(sub_cmd, groups)
|
||||
|
||||
if sub_cmd.endswith('WITH'):
|
||||
sub_cmd = sub_cmd.replace(' WITH', '')
|
||||
@ -497,7 +512,7 @@ def _role_create(name,
|
||||
cmd = _psql_cmd('-c', sub_cmd, host=host, user=user, port=port,
|
||||
maintenance_db=maintenance_db, password=password)
|
||||
return _run_psql(cmd, runas=runas, password=password, host=host,
|
||||
run_cmd="cmd.run")
|
||||
run_cmd='cmd.run')
|
||||
|
||||
|
||||
def user_create(username,
|
||||
@ -519,7 +534,9 @@ def user_create(username,
|
||||
|
||||
CLI Examples::
|
||||
|
||||
salt '*' postgres.user_create 'username' user='user' host='hostname' port='port' password='password' rolepassword='rolepassword'
|
||||
salt '*' postgres.user_create 'username' user='user' \\
|
||||
host='hostname' port='port' password='password' \\
|
||||
rolepassword='rolepassword'
|
||||
'''
|
||||
return _role_create(username,
|
||||
True,
|
||||
@ -558,20 +575,20 @@ def _role_update(name,
|
||||
# check if user exists
|
||||
if not user_exists(name, user, host, port, maintenance_db, password,
|
||||
runas=runas):
|
||||
log.info('User \'{0}\' does not exist'.format(name,))
|
||||
log.info('User {0!r} does not exist'.format(name))
|
||||
return False
|
||||
|
||||
sub_cmd = 'ALTER ROLE {0} WITH'.format(name, )
|
||||
sub_cmd = 'ALTER ROLE {0} WITH'.format(name)
|
||||
if rolepassword is not None:
|
||||
sub_cmd = '{0} PASSWORD \'{1}\''.format(sub_cmd, rolepassword)
|
||||
sub_cmd = '{0} PASSWORD {1!r}'.format(sub_cmd, rolepassword)
|
||||
if createdb:
|
||||
sub_cmd = '{0} CREATEDB'.format(sub_cmd, )
|
||||
sub_cmd = '{0} CREATEDB'.format(sub_cmd)
|
||||
if createuser:
|
||||
sub_cmd = '{0} CREATEUSER'.format(sub_cmd, )
|
||||
sub_cmd = '{0} CREATEUSER'.format(sub_cmd)
|
||||
if encrypted:
|
||||
sub_cmd = '{0} ENCRYPTED'.format(sub_cmd, )
|
||||
sub_cmd = '{0} ENCRYPTED'.format(sub_cmd)
|
||||
if replication:
|
||||
sub_cmd = '{0} REPLICATION'.format(sub_cmd, )
|
||||
sub_cmd = '{0} REPLICATION'.format(sub_cmd)
|
||||
|
||||
if sub_cmd.endswith('WITH'):
|
||||
sub_cmd = sub_cmd.replace(' WITH', '')
|
||||
@ -583,7 +600,7 @@ def _role_update(name,
|
||||
cmd = _psql_cmd('-c', sub_cmd, host=host, user=user, port=port,
|
||||
maintenance_db=maintenance_db, password=password)
|
||||
return _run_psql(cmd, runas=runas, password=password, host=host,
|
||||
run_cmd="cmd.run")
|
||||
run_cmd='cmd.run')
|
||||
|
||||
|
||||
def user_update(username,
|
||||
@ -604,7 +621,9 @@ def user_update(username,
|
||||
|
||||
CLI Examples::
|
||||
|
||||
salt '*' postgres.user_create 'username' user='user' host='hostname' port='port' password='password' rolepassword='rolepassword'
|
||||
salt '*' postgres.user_create 'username' user='user' \\
|
||||
host='hostname' port='port' password='password' \\
|
||||
rolepassword='rolepassword'
|
||||
'''
|
||||
return _role_update(username,
|
||||
user,
|
||||
@ -630,20 +649,21 @@ def _role_remove(name, user=None, host=None, port=None, maintenance_db=None,
|
||||
# check if user exists
|
||||
if not user_exists(name, user, host, port, maintenance_db,
|
||||
password=password, runas=runas):
|
||||
log.info('User \'{0}\' does not exist'.format(name,))
|
||||
log.info('User {0!r} does not exist'.format(name))
|
||||
return False
|
||||
|
||||
# user exists, proceed
|
||||
sub_cmd = 'DROP ROLE {0}'.format(name)
|
||||
cmd = _psql_cmd('-c', sub_cmd, host=host, user=user, port=port,
|
||||
maintenance_db=maintenance_db, password=password)
|
||||
_run_psql(cmd, runas=runas, password=password, host=host,
|
||||
run_cmd="cmd.run")
|
||||
_run_psql(
|
||||
cmd, runas=runas, password=password, host=host, run_cmd='cmd.run'
|
||||
)
|
||||
if not user_exists(name, user, host, port, maintenance_db,
|
||||
password=password, runas=runas):
|
||||
return True
|
||||
else:
|
||||
log.info('Failed to delete user \'{0}\'.'.format(name, ))
|
||||
log.info('Failed to delete user {0!r}.'.format(name))
|
||||
return False
|
||||
|
||||
|
||||
@ -687,7 +707,9 @@ def group_create(groupname,
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' postgres.group_create 'groupname' user='user' host='hostname' port='port' password='password' rolepassword='rolepassword'
|
||||
salt '*' postgres.group_create 'groupname' user='user' \\
|
||||
host='hostname' port='port' password='password' \\
|
||||
rolepassword='rolepassword'
|
||||
'''
|
||||
return _role_create(groupname,
|
||||
False,
|
||||
@ -724,7 +746,9 @@ def group_update(groupname,
|
||||
|
||||
CLI Examples::
|
||||
|
||||
salt '*' postgres.group_update 'username' user='user' host='hostname' port='port' password='password' rolepassword='rolepassword'
|
||||
salt '*' postgres.group_update 'username' user='user' \\
|
||||
host='hostname' port='port' password='password' \\
|
||||
rolepassword='rolepassword'
|
||||
'''
|
||||
return _role_update(groupname,
|
||||
user,
|
||||
@ -758,13 +782,14 @@ def group_remove(groupname,
|
||||
return _role_remove(groupname, user, host, port, maintenance_db,
|
||||
password, runas)
|
||||
|
||||
|
||||
def owner_to(dbname,
|
||||
ownername,
|
||||
user=None,
|
||||
host=None,
|
||||
port=None,
|
||||
password=None,
|
||||
runas=None):
|
||||
ownername,
|
||||
user=None,
|
||||
host=None,
|
||||
port=None,
|
||||
password=None,
|
||||
runas=None):
|
||||
'''
|
||||
Set the owner of all schemas, functions, tables, views and sequences to
|
||||
the given username.
|
||||
@ -776,54 +801,52 @@ def owner_to(dbname,
|
||||
|
||||
sqlfile = tempfile.NamedTemporaryFile()
|
||||
sqlfile.write('begin;\n')
|
||||
sqlfile.write('alter database {0} owner to {1};\n'.format(dbname, ownername))
|
||||
|
||||
queries = (
|
||||
# schemas
|
||||
(
|
||||
'alter schema %(n)s owner to %(owner)s;',
|
||||
'select quote_ident(schema_name) as n from information_schema.schemata;'
|
||||
),
|
||||
# tables and views
|
||||
(
|
||||
'alter table %(n)s owner to %(owner)s;',
|
||||
"select quote_ident(table_schema)||'.'||quote_ident(table_name) as n " +
|
||||
"from information_schema.tables where table_schema not in ('pg_catalog', 'information_schema');"
|
||||
),
|
||||
# functions
|
||||
(
|
||||
'alter function %(n)s owner to %(owner)s;',
|
||||
"select p.oid::regprocedure::text as n from pg_catalog.pg_proc p " +
|
||||
"join pg_catalog.pg_namespace ns on p.pronamespace=ns.oid where ns.nspname not in ('pg_catalog', 'information_schema') " +
|
||||
" and not p.proisagg;"
|
||||
),
|
||||
# aggregate functions
|
||||
(
|
||||
'alter aggregate %(n)s owner to %(owner)s;',
|
||||
"select p.oid::regprocedure::text as n from pg_catalog.pg_proc p " +
|
||||
"join pg_catalog.pg_namespace ns on p.pronamespace=ns.oid where ns.nspname not in ('pg_catalog', 'information_schema') " +
|
||||
" and p.proisagg;"
|
||||
),
|
||||
# sequences
|
||||
(
|
||||
'alter sequence %(n)s owner to %(owner)s;',
|
||||
"select quote_ident(sequence_schema)||'.'||quote_ident(sequence_name) as n from information_schema.sequences;"
|
||||
sqlfile.write(
|
||||
'alter database {0} owner to {1};\n'.format(
|
||||
dbname, ownername
|
||||
)
|
||||
)
|
||||
|
||||
queries = (
|
||||
# schemas
|
||||
('alter schema ${n} owner to ${owner};',
|
||||
'select quote_ident(schema_name) as n from '
|
||||
'information_schema.schemata;'),
|
||||
# tables and views
|
||||
('alter table ${n} owner to ${owner};',
|
||||
'select quote_ident(table_schema)||\'.\'||quote_ident(table_name) as '
|
||||
'n from information_schema.tables where table_schema not in '
|
||||
'(\'pg_catalog\', \'information_schema\');'),
|
||||
# functions
|
||||
('alter function ${n} owner to ${owner};',
|
||||
'select p.oid::regprocedure::text as n from pg_catalog.pg_proc p '
|
||||
'join pg_catalog.pg_namespace ns on p.pronamespace=ns.oid where '
|
||||
'ns.nspname not in (\'pg_catalog\', \'information_schema\') '
|
||||
' and not p.proisagg;'),
|
||||
# aggregate functions
|
||||
('alter aggregate ${n} owner to ${owner};',
|
||||
'select p.oid::regprocedure::text as n from pg_catalog.pg_proc p '
|
||||
'join pg_catalog.pg_namespace ns on p.pronamespace=ns.oid where '
|
||||
'ns.nspname not in (\'pg_catalog\', \'information_schema\') '
|
||||
'and p.proisagg;'),
|
||||
# sequences
|
||||
('alter sequence ${n} owner to ${owner};',
|
||||
'select quote_ident(sequence_schema)||\'.\'||'
|
||||
'quote_ident(sequence_name) as n from information_schema.sequences;')
|
||||
)
|
||||
|
||||
for fmt, query in queries:
|
||||
ret = psql_query(query, user=user, host=host, port=port, maintenance_db=dbname,
|
||||
password=password, runas=runas)
|
||||
ret = psql_query(query, user=user, host=host, port=port,
|
||||
maintenance_db=dbname, password=password, runas=runas)
|
||||
for row in ret:
|
||||
line = fmt % {'owner': ownername, 'n': row['n']}
|
||||
sqlfile.write(line + "\n")
|
||||
sqlfile.write(fmt.format(owner=ownername, n=row['n']) + '\n')
|
||||
|
||||
sqlfile.write('commit;\n')
|
||||
sqlfile.flush()
|
||||
os.chmod(sqlfile.name, 0644) # ensure psql can read the file
|
||||
os.chmod(sqlfile.name, 0644) # ensure psql can read the file
|
||||
|
||||
# run the generated sqlfile in the db
|
||||
cmd = _psql_cmd('-f', sqlfile.name, user=user, host=host, port=port,
|
||||
password=password, maintenance_db=dbname)
|
||||
password=password, maintenance_db=dbname)
|
||||
cmdret = _run_psql(cmd, runas=runas, password=password)
|
||||
return cmdret
|
||||
|
Loading…
Reference in New Issue
Block a user