mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
parent
037bcdea27
commit
a826720371
@ -1993,3 +1993,206 @@ def schema_list(dbname,
|
||||
ret[row['name']] = retrow
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def language_list(
|
||||
maintenance_db,
|
||||
user=None,
|
||||
host=None,
|
||||
port=None,
|
||||
password=None,
|
||||
runas=None):
|
||||
'''
|
||||
Return a list of languages in a database.
|
||||
|
||||
CLI Example:
|
||||
.. code-block:: bash
|
||||
salt '*' postgres.language_list dbname
|
||||
|
||||
maintenance_db
|
||||
The database to check
|
||||
|
||||
user
|
||||
database username if different from config or default
|
||||
|
||||
password
|
||||
user password if any password for a specified user
|
||||
|
||||
host
|
||||
Database host if different from config or default
|
||||
|
||||
port
|
||||
Database port if different from config or default
|
||||
|
||||
runas
|
||||
System user all operations should be performed on behalf of
|
||||
'''
|
||||
|
||||
ret = {}
|
||||
query = 'SELECT lanname AS "Name" FROM pg_language'
|
||||
|
||||
rows = psql_query(
|
||||
query,
|
||||
runas=runas,
|
||||
host=host,
|
||||
user=user,
|
||||
port=port,
|
||||
maintenance_db=maintenance_db,
|
||||
password=password)
|
||||
|
||||
for row in rows:
|
||||
ret[row['Name']] = row['Name']
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def language_exists(
|
||||
name,
|
||||
maintenance_db,
|
||||
user=None,
|
||||
host=None,
|
||||
port=None,
|
||||
password=None,
|
||||
runas=None):
|
||||
'''
|
||||
Checks if language exists in a database.
|
||||
|
||||
CLI Example:
|
||||
.. code-block:: bash
|
||||
salt '*' postgres.language_exists plpgsql dbname
|
||||
|
||||
name
|
||||
Language to check for
|
||||
|
||||
maintenance_db
|
||||
The database to check in
|
||||
|
||||
user
|
||||
database username if different from config or default
|
||||
|
||||
password
|
||||
user password if any password for a specified user
|
||||
|
||||
host
|
||||
Database host if different from config or default
|
||||
|
||||
port
|
||||
Database port if different from config or default
|
||||
|
||||
runas
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
'''
|
||||
|
||||
languages = language_list(
|
||||
maintenance_db, user=user, host=host,
|
||||
port=port, password=password,
|
||||
runas=runas)
|
||||
|
||||
return name in languages
|
||||
|
||||
|
||||
def language_create(name,
|
||||
maintenance_db,
|
||||
user=None,
|
||||
host=None,
|
||||
port=None,
|
||||
password=None,
|
||||
runas=None):
|
||||
'''
|
||||
Installs a language into a database
|
||||
|
||||
CLI Example:
|
||||
.. code-block:: bash
|
||||
salt '*' postgres.language_create plpgsql dbname
|
||||
|
||||
name
|
||||
Language to install
|
||||
|
||||
maintenance_db
|
||||
The database to install the language in
|
||||
|
||||
user
|
||||
database username if different from config or default
|
||||
|
||||
password
|
||||
user password if any password for a specified user
|
||||
|
||||
host
|
||||
Database host if different from config or default
|
||||
|
||||
port
|
||||
Database port if different from config or default
|
||||
|
||||
runas
|
||||
System user all operations should be performed on behalf of
|
||||
'''
|
||||
|
||||
if language_exists(name, maintenance_db):
|
||||
log.info('Language %s already exists in %s', name, maintenance_db)
|
||||
return False
|
||||
|
||||
query = 'CREATE LANGUAGE {0}'.format(name)
|
||||
|
||||
ret = _psql_prepare_and_run(['-c', query],
|
||||
user=user,
|
||||
host=host,
|
||||
port=port,
|
||||
maintenance_db=maintenance_db,
|
||||
password=password,
|
||||
runas=runas)
|
||||
|
||||
return ret['retcode'] == 0
|
||||
|
||||
|
||||
def language_remove(name,
|
||||
maintenance_db,
|
||||
user=None,
|
||||
host=None,
|
||||
port=None,
|
||||
password=None,
|
||||
runas=None):
|
||||
'''
|
||||
Removes a language from a database
|
||||
|
||||
CLI Example:
|
||||
.. code-block:: bash
|
||||
salt '*' postgres.language_remove plpgsql dbname
|
||||
|
||||
name
|
||||
Language to remove
|
||||
|
||||
maintenance_db
|
||||
The database to install the language in
|
||||
|
||||
user
|
||||
database username if different from config or default
|
||||
|
||||
password
|
||||
user password if any password for a specified user
|
||||
|
||||
host
|
||||
Database host if different from config or default
|
||||
|
||||
port
|
||||
Database port if different from config or default
|
||||
|
||||
runas
|
||||
System user all operations should be performed on behalf of
|
||||
'''
|
||||
|
||||
if not language_exists(name, maintenance_db):
|
||||
log.info('Language %s does not exist in %s', name, maintenance_db)
|
||||
return False
|
||||
|
||||
query = 'DROP LANGUAGE {0}'.format(name)
|
||||
|
||||
ret = _psql_prepare_and_run(['-c', query],
|
||||
user=user,
|
||||
host=host,
|
||||
port=port,
|
||||
runas=runas,
|
||||
maintenance_db=maintenance_db,
|
||||
password=password)
|
||||
|
||||
return ret['retcode'] == 0
|
||||
|
162
salt/states/postgres_language.py
Normal file
162
salt/states/postgres_language.py
Normal file
@ -0,0 +1,162 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Management of PostgreSQL languages
|
||||
==================================
|
||||
|
||||
The postgres_language module is used to create and manage Postgres languages.
|
||||
Languages can be set as either absent or present
|
||||
|
||||
.. code-block:: yaml
|
||||
plpgsql:
|
||||
postgres_language.present:
|
||||
- maintenance_db: testdb
|
||||
|
||||
.. code-block:: yaml
|
||||
plpgsql:
|
||||
postgres_language.absent:
|
||||
- maintenance_db: testdb
|
||||
|
||||
.. versionadded:: Boron
|
||||
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only load if the postgres module is present
|
||||
'''
|
||||
return 'postgres.language_create' in __salt__
|
||||
|
||||
|
||||
def present(name,
|
||||
maintenance_db,
|
||||
user=None,
|
||||
db_password=None,
|
||||
db_host=None,
|
||||
db_port=None,
|
||||
db_user=None):
|
||||
'''
|
||||
Ensure that a named language is present in the specified
|
||||
database.
|
||||
|
||||
name
|
||||
The name of the language to install
|
||||
|
||||
maintenance_db
|
||||
The name of the database in which the language is to be installed
|
||||
|
||||
user
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
db_user
|
||||
database username if different from config or default
|
||||
|
||||
db_password
|
||||
user password if any password for a specified user
|
||||
|
||||
db_host
|
||||
Database host if different from config or default
|
||||
|
||||
db_port
|
||||
Database port if different from config or default
|
||||
'''
|
||||
ret = {
|
||||
'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': 'Language {0} is already installed'.format(name)
|
||||
}
|
||||
|
||||
dbargs = {
|
||||
'runas': user,
|
||||
'host': db_host,
|
||||
'user': db_user,
|
||||
'port': db_port,
|
||||
'password': db_password,
|
||||
}
|
||||
|
||||
languages = __salt__['postgres.language_list'](maintenance_db, **dbargs)
|
||||
|
||||
if name not in languages:
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'Language {0} is set to be installed'.format(
|
||||
name)
|
||||
return ret
|
||||
|
||||
if __salt__['postgres.language_create'](name, maintenance_db,
|
||||
**dbargs):
|
||||
ret['comment'] = 'Language {0} has been installed'.format(name)
|
||||
ret['changes'][name] = 'Present'
|
||||
else:
|
||||
ret['comment'] = 'Failed to install language {0}'.format(name)
|
||||
ret['result'] = False
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def absent(
|
||||
name,
|
||||
maintenance_db,
|
||||
user=None,
|
||||
db_password=None,
|
||||
db_host=None,
|
||||
db_port=None,
|
||||
db_user=None):
|
||||
'''
|
||||
Ensure that a named language is absent in the specified
|
||||
database.
|
||||
|
||||
name
|
||||
The name of the language to remove
|
||||
|
||||
maintenance_db
|
||||
The name of the database in which the language is to be installed
|
||||
|
||||
user
|
||||
System user all operations should be performed on behalf of
|
||||
|
||||
db_user
|
||||
database username if different from config or default
|
||||
|
||||
db_password
|
||||
user password if any password for a specified user
|
||||
|
||||
db_host
|
||||
Database host if different from config or default
|
||||
|
||||
db_port
|
||||
Database port if different from config or default
|
||||
'''
|
||||
ret = {
|
||||
'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': ''
|
||||
}
|
||||
|
||||
dbargs = {
|
||||
'runas': user,
|
||||
'host': db_host,
|
||||
'user': db_user,
|
||||
'port': db_port,
|
||||
'password': db_password,
|
||||
}
|
||||
|
||||
if __salt__['postgres.language_exists'](name, maintenance_db, **dbargs):
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'Language {0} is set to be removed'.format(name)
|
||||
return ret
|
||||
if __salt__['postgres.language_remove'](name, **dbargs):
|
||||
ret['comment'] = 'Language {0} has been removed'.format(name)
|
||||
ret['changes'][name] = 'Absent'
|
||||
return ret
|
||||
else:
|
||||
ret['comment'] = 'Failed to remove language {0}'.format(name)
|
||||
ret['result'] = False
|
||||
|
||||
ret['comment'] = 'Language {0} is not present ' \
|
||||
'so it cannot be removed'.format(name)
|
||||
return ret
|
@ -33,6 +33,14 @@ test_list_schema_csv = (
|
||||
'pg_toast,postgres,""'
|
||||
)
|
||||
|
||||
test_list_language_csv = (
|
||||
'Name\n'
|
||||
'internal\n'
|
||||
'c\n'
|
||||
'sql\n'
|
||||
'plpgsql\n'
|
||||
)
|
||||
|
||||
|
||||
if NO_MOCK is False:
|
||||
SALT_STUB = {
|
||||
@ -862,6 +870,125 @@ class PostgresTestCase(TestCase):
|
||||
)
|
||||
self.assertFalse(ret)
|
||||
|
||||
@patch('salt.modules.postgres._run_psql',
|
||||
Mock(return_value={'retcode': 0,
|
||||
'stdout': test_list_language_csv}))
|
||||
def test_language_list(self):
|
||||
'''
|
||||
Test language listing
|
||||
'''
|
||||
ret = postgres.language_list(
|
||||
'testdb',
|
||||
user='testuser',
|
||||
host='testhost',
|
||||
port='testport',
|
||||
password='foo'
|
||||
)
|
||||
self.assertDictEqual(ret,
|
||||
{'c': 'c',
|
||||
'internal': 'internal',
|
||||
'plpgsql': 'plpgsql',
|
||||
'sql': 'sql'})
|
||||
|
||||
@patch('salt.modules.postgres._run_psql',
|
||||
Mock(return_value={'retcode': 0}))
|
||||
@patch('salt.modules.postgres.psql_query',
|
||||
Mock(return_value=[
|
||||
{'Name': 'internal'},
|
||||
{'Name': 'c'},
|
||||
{'Name': 'sql'},
|
||||
{'Name': 'plpgsql'}]))
|
||||
@patch('salt.modules.postgres.language_exists', Mock(return_value=True))
|
||||
def test_language_exists(self):
|
||||
'''
|
||||
Test language existance check
|
||||
'''
|
||||
ret = postgres.language_exists(
|
||||
'sql',
|
||||
'testdb'
|
||||
)
|
||||
self.assertTrue(ret)
|
||||
|
||||
@patch('salt.modules.postgres._run_psql',
|
||||
Mock(return_value={'retcode': 0}))
|
||||
@patch('salt.modules.postgres.language_exists', Mock(return_value=False))
|
||||
def test_language_create(self):
|
||||
'''
|
||||
Test language creation - does not exist in db
|
||||
'''
|
||||
postgres.language_create(
|
||||
'plpythonu',
|
||||
'testdb',
|
||||
runas='user',
|
||||
host='testhost',
|
||||
port='testport',
|
||||
user='testuser',
|
||||
password='testpassword'
|
||||
)
|
||||
postgres._run_psql.assert_called_once_with(
|
||||
['/usr/bin/pgsql', '--no-align', '--no-readline',
|
||||
'--no-password', '--username', 'testuser', '--host',
|
||||
'testhost', '--port', 'testport', '--dbname', 'testdb',
|
||||
'-c', 'CREATE LANGUAGE plpythonu'],
|
||||
host='testhost', port='testport',
|
||||
password='testpassword', user='testuser', runas='user')
|
||||
|
||||
@patch('salt.modules.postgres.language_exists', Mock(return_value=True))
|
||||
def test_language_create_exists(self):
|
||||
'''
|
||||
Test language creation - already exists in db
|
||||
'''
|
||||
ret = postgres.language_create(
|
||||
'plpythonu',
|
||||
'testdb',
|
||||
runas='user',
|
||||
host='testhost',
|
||||
port='testport',
|
||||
user='testuser',
|
||||
password='testpassword'
|
||||
)
|
||||
self.assertFalse(ret)
|
||||
|
||||
@patch('salt.modules.postgres._run_psql',
|
||||
Mock(return_value={'retcode': 0}))
|
||||
@patch('salt.modules.postgres.language_exists', Mock(return_value=True))
|
||||
def test_language_remove(self):
|
||||
'''
|
||||
Test language removal - exists in db
|
||||
'''
|
||||
postgres.language_remove(
|
||||
'plpgsql',
|
||||
'testdb',
|
||||
runas='user',
|
||||
host='testhost',
|
||||
port='testport',
|
||||
user='testuser',
|
||||
password='testpassword'
|
||||
)
|
||||
postgres._run_psql.assert_called_once_with(
|
||||
['/usr/bin/pgsql', '--no-align', '--no-readline',
|
||||
'--no-password', '--username', 'testuser', '--host',
|
||||
'testhost', '--port', 'testport', '--dbname', 'testdb',
|
||||
'-c', 'DROP LANGUAGE plpgsql'],
|
||||
host='testhost', port='testport',
|
||||
password='testpassword', user='testuser', runas='user')
|
||||
|
||||
@patch('salt.modules.postgres.language_exists', Mock(return_value=False))
|
||||
def test_language_remove_non_exist(self):
|
||||
'''
|
||||
Test language removal - does not exist in db
|
||||
'''
|
||||
ret = postgres.language_remove(
|
||||
'plpgsql',
|
||||
'testdb',
|
||||
runas='user',
|
||||
host='testhost',
|
||||
port='testport',
|
||||
user='testuser',
|
||||
password='testpassword'
|
||||
)
|
||||
self.assertFalse(ret)
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(PostgresTestCase, needs_daemon=False)
|
||||
|
129
tests/unit/states/postgres_language_test.py
Normal file
129
tests/unit/states/postgres_language_test.py
Normal file
@ -0,0 +1,129 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Andrew Colin Kissa <andrew@topdog.za.net>`
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
from salttesting import skipIf, TestCase
|
||||
from salttesting.mock import (
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON,
|
||||
MagicMock,
|
||||
patch
|
||||
)
|
||||
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
from salt.states import postgres_language
|
||||
|
||||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class PostgresLanguageTestCase(TestCase):
|
||||
'''
|
||||
Test cases for salt.states.postgres_language
|
||||
'''
|
||||
|
||||
def setUp(self):
|
||||
'''
|
||||
Setup data for the tests
|
||||
'''
|
||||
postgres_language.__opts__ = {}
|
||||
postgres_language.__salt__ = {}
|
||||
self.name = 'plpgsql'
|
||||
self.ret = {'name': self.name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
self.mock_true = MagicMock(return_value=True)
|
||||
self.mock_false = MagicMock(return_value=False)
|
||||
self.mock_empty_language_list = MagicMock(return_value={})
|
||||
self.mock_language_list = MagicMock(
|
||||
return_value={'plpgsql': self.name})
|
||||
|
||||
|
||||
def test_present_existing(self):
|
||||
'''
|
||||
Test present, language is already present in database
|
||||
'''
|
||||
with patch.dict(postgres_language.__salt__,
|
||||
{'postgres.language_list': self.mock_language_list}):
|
||||
comt = 'Language {0} is already installed'.format(self.name)
|
||||
self.ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(
|
||||
postgres_language.present(self.name, 'testdb'), self.ret)
|
||||
|
||||
def test_present_non_existing_pass(self):
|
||||
'''
|
||||
Test present, language not present in database - pass
|
||||
'''
|
||||
with patch.dict(postgres_language.__salt__,
|
||||
{'postgres.language_list': self.mock_empty_language_list,
|
||||
'postgres.language_create': self.mock_true}):
|
||||
with patch.dict(postgres_language.__opts__, {'test': True}):
|
||||
comt = 'Language {0} is set to be installed'.format(self.name)
|
||||
self.ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(
|
||||
postgres_language.present(self.name, 'testdb'), self.ret)
|
||||
|
||||
with patch.dict(postgres_language.__opts__, {'test': False}):
|
||||
comt = 'Language {0} has been installed'.format(self.name)
|
||||
self.ret.update({'comment': comt,
|
||||
'result': True,
|
||||
'changes': {'plpgsql': 'Present'}})
|
||||
self.assertDictEqual(
|
||||
postgres_language.present(self.name, 'testdb'), self.ret)
|
||||
|
||||
def test_present_non_existing_fail(self):
|
||||
'''
|
||||
Test present, language not present in database - fail
|
||||
'''
|
||||
with patch.dict(postgres_language.__salt__,
|
||||
{'postgres.language_list': self.mock_empty_language_list,
|
||||
'postgres.language_create': self.mock_false}):
|
||||
with patch.dict(postgres_language.__opts__, {'test': True}):
|
||||
comt = 'Language {0} is set to be installed'.format(self.name)
|
||||
self.ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(
|
||||
postgres_language.present(self.name, 'testdb'), self.ret)
|
||||
|
||||
with patch.dict(postgres_language.__opts__, {'test': False}):
|
||||
comt = 'Failed to install language {0}'.format(self.name)
|
||||
self.ret.update({'comment': comt, 'result': False})
|
||||
self.assertDictEqual(
|
||||
postgres_language.present(self.name, 'testdb'), self.ret)
|
||||
|
||||
def test_absent_existing(self):
|
||||
'''
|
||||
Test absent, language present in database
|
||||
'''
|
||||
with patch.dict(postgres_language.__salt__,
|
||||
{'postgres.language_exists': self.mock_true,
|
||||
'postgres.language_remove': self.mock_true}):
|
||||
with patch.dict(postgres_language.__opts__, {'test': True}):
|
||||
comt = 'Language {0} is set to be removed'.format(self.name)
|
||||
self.ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(
|
||||
postgres_language.absent(self.name, 'testdb'), self.ret)
|
||||
|
||||
with patch.dict(postgres_language.__opts__, {'test': False}):
|
||||
comt = 'Language {0} has been removed'.format(self.name)
|
||||
self.ret.update({'comment': comt,
|
||||
'result': True,
|
||||
'changes': {'plpgsql': 'Absent'}})
|
||||
self.assertDictEqual(
|
||||
postgres_language.absent(self.name, 'testdb'), self.ret)
|
||||
|
||||
def test_absent_non_existing(self):
|
||||
'''
|
||||
Test absent, language not present in database
|
||||
'''
|
||||
with patch.dict(postgres_language.__salt__,
|
||||
{'postgres.language_exists': self.mock_false}):
|
||||
with patch.dict(postgres_language.__opts__, {'test': True}):
|
||||
comt = 'Language {0} is not present so ' \
|
||||
'it cannot be removed'.format(self.name)
|
||||
self.ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(
|
||||
postgres_language.absent(self.name, 'testdb'), self.ret)
|
Loading…
Reference in New Issue
Block a user