mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
New module postgresql_sequence (#55027)
* postgresql_sequence: initial commit with new module and tests * change return variables and adjust tests * fix sanity checks * fix linter errors * change formatting functions and put params alphabetically * add new examples and remove restrict option * remove restrict option * remove `required: false` * add links to documentation * change some minor parts in documentation * add new integration tests for ** drop cascade ** change owner * change usage of owner and created a test case for set owner during creation * remove some documents and use docsfragments * add aliases for minvalue and maxvalue * change to warn if sequence not exists but should be removed * use connect_to_db from module_utils/postgres.py * add checkmode for several tests * fix psycopg2 import and connect_to_db * add a test for drop nonexistent sequence * change get_info funcrtion to use only one SQL statement * rewrite the module for cleaner code * remove psycopg2 * change check_mode behavior * add docstrings for class and methods * add test for create sequence with owner in check_mode * fix typo in set_schema() * fix docu and cleanup the code * adjust documentation for state, schema and newschema * remove mutually_exclusive for 'absent' * remove unused code comments * remove warning for drop non-exicsting sequence * change autocommit condition * adjust state documentation
This commit is contained in:
parent
03d64cd9ea
commit
07d446825a
4 changed files with 1322 additions and 1 deletions
|
@ -38,7 +38,7 @@ class UnclosedQuoteError(SQLParseError):
|
|||
# maps a type of identifier to the maximum number of dot levels that are
|
||||
# allowed to specify that identifier. For example, a database column can be
|
||||
# specified by up to 4 levels: database.schema.table.column
|
||||
_PG_IDENTIFIER_TO_DOT_LEVEL = dict(database=1, schema=2, table=3, column=4, role=1, tablespace=1)
|
||||
_PG_IDENTIFIER_TO_DOT_LEVEL = dict(database=1, schema=2, table=3, column=4, role=1, tablespace=1, sequence=3)
|
||||
_MYSQL_IDENTIFIER_TO_DOT_LEVEL = dict(database=1, table=2, column=3, role=1, vars=1)
|
||||
|
||||
|
||||
|
|
621
lib/ansible/modules/database/postgresql/postgresql_sequence.py
Normal file
621
lib/ansible/modules/database/postgresql/postgresql_sequence.py
Normal file
|
@ -0,0 +1,621 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2019, Tobias Birkefeld (@tcraxs) <t@craxs.de>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'
|
||||
}
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: postgresql_sequence
|
||||
short_description: Create, drop, or alter a PostgreSQL sequence
|
||||
description:
|
||||
- Allows to create, drop or change the definition of a sequence generator
|
||||
U(https://www.postgresql.org/docs/current/sql-createsequence.html).
|
||||
version_added: '2.9'
|
||||
options:
|
||||
sequence:
|
||||
description:
|
||||
- The name of the sequence.
|
||||
required: true
|
||||
type: str
|
||||
aliases:
|
||||
- name
|
||||
state:
|
||||
description:
|
||||
- The sequence state.
|
||||
- If I(state=absent) other options will be ignored except of I(name) and
|
||||
I(schema).
|
||||
default: present
|
||||
choices: [ absent, present ]
|
||||
type: str
|
||||
data_type:
|
||||
description:
|
||||
- Specifies the data type of the sequence. Valid types are bigint, integer,
|
||||
and smallint. bigint is the default. The data type determines the default
|
||||
minimum and maximum values of the sequence. For more info see the
|
||||
documention
|
||||
U(https://www.postgresql.org/docs/current/sql-createsequence.html).
|
||||
- Supported from PostgreSQL 10.
|
||||
choices: [ bigint, integer, smallint ]
|
||||
type: str
|
||||
increment:
|
||||
description:
|
||||
- Increment specifies which value is added to the current sequence value
|
||||
to create a new value.
|
||||
- A positive value will make an ascending sequence, a negative one a
|
||||
descending sequence. The default value is 1.
|
||||
type: int
|
||||
minvalue:
|
||||
description:
|
||||
- Minvalue determines the minimum value a sequence can generate. The
|
||||
default for an ascending sequence is 1. The default for a descending
|
||||
sequence is the minimum value of the data type.
|
||||
type: int
|
||||
aliases:
|
||||
- min
|
||||
maxvalue:
|
||||
description:
|
||||
- Maxvalue determines the maximum value for the sequence. The default for
|
||||
an ascending sequence is the maximum
|
||||
value of the data type. The default for a descending sequence is -1.
|
||||
type: int
|
||||
aliases:
|
||||
- max
|
||||
start:
|
||||
description:
|
||||
- Start allows the sequence to begin anywhere. The default starting value
|
||||
is I(minvalue) for ascending sequences and I(maxvalue) for descending
|
||||
ones.
|
||||
type: int
|
||||
cache:
|
||||
description:
|
||||
- Cache specifies how many sequence numbers are to be preallocated and
|
||||
stored in memory for faster access. The minimum value is 1 (only one
|
||||
value can be generated at a time, i.e., no cache), and this is also
|
||||
the default.
|
||||
type: int
|
||||
cycle:
|
||||
description:
|
||||
- The cycle option allows the sequence to wrap around when the I(maxvalue)
|
||||
or I(minvalue) has been reached by an ascending or descending sequence
|
||||
respectively. If the limit is reached, the next number generated will be
|
||||
the minvalue or maxvalue, respectively.
|
||||
- If C(false) (NO CYCLE) is specified, any calls to nextval after the sequence
|
||||
has reached its maximum value will return an error. False (NO CYCLE) is
|
||||
the default.
|
||||
type: bool
|
||||
cascade:
|
||||
description:
|
||||
- Automatically drop objects that depend on the sequence, and in turn all
|
||||
objects that depend on those objects.
|
||||
- Ignored if I(state=present).
|
||||
- Only used with I(state=absent).
|
||||
type: bool
|
||||
rename_to:
|
||||
description:
|
||||
- The new name for the I(sequence).
|
||||
- Works only for existing sequences.
|
||||
type: str
|
||||
owner:
|
||||
description:
|
||||
- Set the owner for the I(sequence).
|
||||
type: str
|
||||
schema:
|
||||
description:
|
||||
- The schema of the I(sequence). This is be used to create and relocate
|
||||
a I(sequence) in the given schema.
|
||||
default: public
|
||||
type: str
|
||||
newschema:
|
||||
description:
|
||||
- The new schema for the I(sequence). Will be used for moving a
|
||||
I(sequence) to another I(schema).
|
||||
- Works only for existing sequences.
|
||||
type: str
|
||||
session_role:
|
||||
description:
|
||||
- Switch to session_role after connecting. The specified I(session_role)
|
||||
must be a role that the current I(login_user) is a member of.
|
||||
- Permissions checking for SQL commands is carried out as though
|
||||
the I(session_role) were the one that had logged in originally.
|
||||
type: str
|
||||
db:
|
||||
description:
|
||||
- Name of database to connect to and run queries against.
|
||||
type: str
|
||||
aliases:
|
||||
- database
|
||||
- login_db
|
||||
notes:
|
||||
- If you do not pass db parameter, sequence will be created in the database
|
||||
named postgres.
|
||||
author:
|
||||
- Tobias Birkefeld (@tcraxs)
|
||||
extends_documentation_fragment: postgres
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
- name: Create an ascending bigint sequence called foobar in the default
|
||||
database
|
||||
postgresql_sequence:
|
||||
name: foobar
|
||||
|
||||
- name: Create an ascending integer sequence called foobar, starting at 101
|
||||
postgresql_sequence:
|
||||
name: foobar
|
||||
data_type: integer
|
||||
start: 101
|
||||
|
||||
- name: Create an descending sequence called foobar, starting at 101 and
|
||||
preallocated 10 sequence numbers in cache
|
||||
postgresql_sequence:
|
||||
name: foobar
|
||||
increment: -1
|
||||
cache: 10
|
||||
start: 101
|
||||
|
||||
- name: Create an ascending sequence called foobar, which cycle between 1 to 10
|
||||
postgresql_sequence:
|
||||
name: foobar
|
||||
cycle: yes
|
||||
min: 1
|
||||
max: 10
|
||||
|
||||
- name: Create an ascending bigint sequence called foobar in the default
|
||||
database with owner foobar
|
||||
postgresql_sequence:
|
||||
name: foobar
|
||||
owner: foobar
|
||||
|
||||
- name: Rename an existing sequence named foo to bar
|
||||
postgresql_sequence:
|
||||
name: foo
|
||||
rename_to: bar
|
||||
|
||||
- name: Change the schema of an existing sequence to foobar
|
||||
postgresql_sequence:
|
||||
name: foobar
|
||||
newschema: foobar
|
||||
|
||||
- name: Change the owner of an existing sequence to foobar
|
||||
postgresql_sequence:
|
||||
name: foobar
|
||||
owner: foobar
|
||||
|
||||
- name: Drop a sequence called foobar
|
||||
postgresql_sequence:
|
||||
name: foobar
|
||||
state: absent
|
||||
|
||||
- name: Drop a sequence called foobar with cascade
|
||||
postgresql_sequence:
|
||||
name: foobar
|
||||
cascade: yes
|
||||
state: absent
|
||||
'''
|
||||
|
||||
RETURN = r'''
|
||||
state:
|
||||
description: Sequence state at the end of execution.
|
||||
returned: always
|
||||
type: str
|
||||
sample: 'present'
|
||||
sequence:
|
||||
description: Sequence name.
|
||||
returned: always
|
||||
type: str
|
||||
sample: 'foobar'
|
||||
queries:
|
||||
description: List of queries that was tried to be executed.
|
||||
returned: always
|
||||
type: str
|
||||
sample: [ "CREATE SEQUENCE \"foo\"" ]
|
||||
schema:
|
||||
description: Name of the schema of the sequence
|
||||
returned: always
|
||||
type: str
|
||||
sample: 'foo'
|
||||
data_type:
|
||||
description: Shows the current data type of the sequence.
|
||||
returned: always
|
||||
type: str
|
||||
sample: 'bigint'
|
||||
increment:
|
||||
description: The value of increment of the sequence. A positive value will
|
||||
make an ascending sequence, a negative one a descending
|
||||
sequence.
|
||||
returned: always
|
||||
type: int
|
||||
sample: '-1'
|
||||
minvalue:
|
||||
description: The value of minvalue of the sequence.
|
||||
returned: always
|
||||
type: int
|
||||
sample: '1'
|
||||
maxvalue:
|
||||
description: The value of maxvalue of the sequence.
|
||||
returned: always
|
||||
type: int
|
||||
sample: '9223372036854775807'
|
||||
start:
|
||||
description: The value of start of the sequence.
|
||||
returned: always
|
||||
type: int
|
||||
sample: '12'
|
||||
cycle:
|
||||
description: Shows if the sequence cycle or not.
|
||||
returned: always
|
||||
type: str
|
||||
sample: 'NO'
|
||||
owner:
|
||||
description: Shows the current owner of the sequence
|
||||
after the successful run of the task.
|
||||
returned: always
|
||||
type: str
|
||||
sample: 'postgres'
|
||||
newname:
|
||||
description: Shows the new sequence name after rename.
|
||||
returned: on success
|
||||
type: str
|
||||
sample: 'barfoo'
|
||||
newschema:
|
||||
description: Shows the new schema of the sequence after schema change.
|
||||
returned: on success
|
||||
type: str
|
||||
sample: 'foobar'
|
||||
'''
|
||||
|
||||
|
||||
try:
|
||||
from psycopg2.extras import DictCursor
|
||||
except ImportError:
|
||||
# psycopg2 is checked by connect_to_db()
|
||||
# from ansible.module_utils.postgres
|
||||
pass
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.database import pg_quote_identifier
|
||||
from ansible.module_utils.postgres import connect_to_db, postgres_common_argument_spec
|
||||
from ansible.module_utils._text import to_native
|
||||
|
||||
|
||||
def exec_sql(obj, query, ddl=False, add_to_executed=True):
|
||||
"""Execute SQL.
|
||||
|
||||
Auxiliary function for PostgreSQL user classes.
|
||||
|
||||
Returns a query result if possible or True/False if ddl=True arg was passed.
|
||||
It necessary for statements that don't return any result (like DDL queries).
|
||||
|
||||
Arguments:
|
||||
obj (obj) -- must be an object of a user class.
|
||||
The object must have module (AnsibleModule class object) and
|
||||
cursor (psycopg cursor object) attributes
|
||||
query (str) -- SQL query to execute
|
||||
ddl (bool) -- must return True or False instead of rows (typical for DDL queries)
|
||||
(default False)
|
||||
add_to_executed (bool) -- append the query to obj.executed_queries attribute
|
||||
"""
|
||||
try:
|
||||
obj.cursor.execute(query)
|
||||
|
||||
if add_to_executed:
|
||||
obj.executed_queries.append(query)
|
||||
|
||||
if not ddl:
|
||||
res = obj.cursor.fetchall()
|
||||
return res
|
||||
return True
|
||||
except Exception as e:
|
||||
obj.module.fail_json(msg="Cannot execute SQL '%s': %s" % (query, to_native(e)))
|
||||
return False
|
||||
|
||||
|
||||
class Sequence(object):
|
||||
"""Implements behavior of CREATE, ALTER or DROP SEQUENCE PostgreSQL command.
|
||||
|
||||
Arguments:
|
||||
module (AnsibleModule) -- object of AnsibleModule class
|
||||
cursor (cursor) -- cursor objec of psycopg2 library
|
||||
|
||||
Attributes:
|
||||
module (AnsibleModule) -- object of AnsibleModule class
|
||||
cursor (cursor) -- cursor objec of psycopg2 library
|
||||
changed (bool) -- something was changed after execution or not
|
||||
executed_queries (list) -- executed queries
|
||||
name (str) -- name of the sequence
|
||||
owner (str) -- name of the owner of the sequence
|
||||
schema (str) -- name of the schema (default: public)
|
||||
data_type (str) -- data type of the sequence
|
||||
start_value (int) -- value of the sequence start
|
||||
minvalue (int) -- minimum value of the sequence
|
||||
maxvalue (int) -- maximum value of the sequence
|
||||
increment (int) -- increment value of the sequence
|
||||
cycle (bool) -- sequence can cycle or not
|
||||
new_name (str) -- name of the renamed sequence
|
||||
new_schema (str) -- name of the new schema
|
||||
exists (bool) -- sequence exists or not
|
||||
"""
|
||||
|
||||
def __init__(self, module, cursor):
|
||||
self.module = module
|
||||
self.cursor = cursor
|
||||
self.executed_queries = []
|
||||
self.name = self.module.params['sequence']
|
||||
self.owner = ''
|
||||
self.schema = self.module.params['schema']
|
||||
self.data_type = ''
|
||||
self.start_value = ''
|
||||
self.minvalue = ''
|
||||
self.maxvalue = ''
|
||||
self.increment = ''
|
||||
self.cycle = ''
|
||||
self.new_name = ''
|
||||
self.new_schema = ''
|
||||
self.exists = False
|
||||
# Collect info
|
||||
self.get_info()
|
||||
|
||||
def get_info(self):
|
||||
"""Getter to refresh and get sequence info"""
|
||||
query = ("SELECT "
|
||||
"s.sequence_schema AS schemaname, "
|
||||
"s.sequence_name AS sequencename, "
|
||||
"pg_get_userbyid(c.relowner) AS sequenceowner, "
|
||||
"s.data_type::regtype AS data_type, "
|
||||
"s.start_value AS start_value, "
|
||||
"s.minimum_value AS min_value, "
|
||||
"s.maximum_value AS max_value, "
|
||||
"s.increment AS increment_by, "
|
||||
"s.cycle_option AS cycle "
|
||||
"FROM information_schema.sequences s "
|
||||
"JOIN pg_class c ON c.relname = s.sequence_name "
|
||||
"LEFT JOIN pg_namespace n ON n.oid = c.relnamespace "
|
||||
"WHERE NOT pg_is_other_temp_schema(n.oid) "
|
||||
"AND c.relkind = 'S'::\"char\" "
|
||||
"AND sequence_name = '%s' "
|
||||
"AND sequence_schema = '%s'" % (self.name,
|
||||
self.schema))
|
||||
|
||||
res = exec_sql(self, query, add_to_executed=False)
|
||||
|
||||
if not res:
|
||||
self.exists = False
|
||||
return False
|
||||
|
||||
if res:
|
||||
self.exists = True
|
||||
self.schema = res[0]['schemaname']
|
||||
self.name = res[0]['sequencename']
|
||||
self.owner = res[0]['sequenceowner']
|
||||
self.data_type = res[0]['data_type']
|
||||
self.start_value = res[0]['start_value']
|
||||
self.minvalue = res[0]['min_value']
|
||||
self.maxvalue = res[0]['max_value']
|
||||
self.increment = res[0]['increment_by']
|
||||
self.cycle = res[0]['cycle']
|
||||
|
||||
def create(self):
|
||||
"""Implements CREATE SEQUENCE command behavior."""
|
||||
query = ['CREATE SEQUENCE']
|
||||
query.append(self.__add_schema())
|
||||
|
||||
if self.module.params.get('data_type'):
|
||||
query.append('AS %s' % self.module.params['data_type'])
|
||||
|
||||
if self.module.params.get('increment'):
|
||||
query.append('INCREMENT BY %s' % self.module.params['increment'])
|
||||
|
||||
if self.module.params.get('minvalue'):
|
||||
query.append('MINVALUE %s' % self.module.params['minvalue'])
|
||||
|
||||
if self.module.params.get('maxvalue'):
|
||||
query.append('MAXVALUE %s' % self.module.params['maxvalue'])
|
||||
|
||||
if self.module.params.get('start'):
|
||||
query.append('START WITH %s' % self.module.params['start'])
|
||||
|
||||
if self.module.params.get('cache'):
|
||||
query.append('CACHE %s' % self.module.params['cache'])
|
||||
|
||||
if self.module.params.get('cycle'):
|
||||
query.append('CYCLE')
|
||||
|
||||
return exec_sql(self, ' '.join(query), ddl=True)
|
||||
|
||||
def drop(self):
|
||||
"""Implements DROP SEQUENCE command behavior."""
|
||||
query = ['DROP SEQUENCE']
|
||||
query.append(self.__add_schema())
|
||||
|
||||
if self.module.params.get('cascade'):
|
||||
query.append('CASCADE')
|
||||
|
||||
return exec_sql(self, ' '.join(query), ddl=True)
|
||||
|
||||
def rename(self):
|
||||
"""Implements ALTER SEQUENCE RENAME TO command behavior."""
|
||||
query = ['ALTER SEQUENCE']
|
||||
query.append(self.__add_schema())
|
||||
query.append('RENAME TO %s' % pg_quote_identifier(self.module.params['rename_to'], 'sequence'))
|
||||
|
||||
return exec_sql(self, ' '.join(query), ddl=True)
|
||||
|
||||
def set_owner(self):
|
||||
"""Implements ALTER SEQUENCE OWNER TO command behavior."""
|
||||
query = ['ALTER SEQUENCE']
|
||||
query.append(self.__add_schema())
|
||||
query.append('OWNER TO %s' % pg_quote_identifier(self.module.params['owner'], 'role'))
|
||||
|
||||
return exec_sql(self, ' '.join(query), ddl=True)
|
||||
|
||||
def set_schema(self):
|
||||
"""Implements ALTER SEQUENCE SET SCHEMA command behavior."""
|
||||
query = ['ALTER SEQUENCE']
|
||||
query.append(self.__add_schema())
|
||||
query.append('SET SCHEMA %s' % pg_quote_identifier(self.module.params['newschema'], 'schema'))
|
||||
|
||||
return exec_sql(self, ' '.join(query), ddl=True)
|
||||
|
||||
def __add_schema(self):
|
||||
return '.'.join([pg_quote_identifier(self.schema, 'schema'),
|
||||
pg_quote_identifier(self.name, 'sequence')])
|
||||
|
||||
|
||||
# ===========================================
|
||||
# Module execution.
|
||||
#
|
||||
|
||||
def main():
|
||||
argument_spec = postgres_common_argument_spec()
|
||||
argument_spec.update(
|
||||
sequence=dict(type='str', required=True, aliases=['name']),
|
||||
state=dict(type='str', default='present', choices=['absent', 'present']),
|
||||
data_type=dict(type='str', choices=['bigint', 'integer', 'smallint']),
|
||||
increment=dict(type='int'),
|
||||
minvalue=dict(type='int', aliases=['min']),
|
||||
maxvalue=dict(type='int', aliases=['max']),
|
||||
start=dict(type='int'),
|
||||
cache=dict(type='int'),
|
||||
cycle=dict(type='bool'),
|
||||
schema=dict(type='str', default='public'),
|
||||
cascade=dict(type='bool'),
|
||||
rename_to=dict(type='str'),
|
||||
owner=dict(type='str'),
|
||||
newschema=dict(type='str'),
|
||||
db=dict(type='str', default='', aliases=['login_db', 'database']),
|
||||
session_role=dict(type='str'),
|
||||
)
|
||||
module = AnsibleModule(
|
||||
argument_spec=argument_spec,
|
||||
supports_check_mode=True,
|
||||
mutually_exclusive=[
|
||||
['rename_to', 'data_type'],
|
||||
['rename_to', 'increment'],
|
||||
['rename_to', 'minvalue'],
|
||||
['rename_to', 'maxvalue'],
|
||||
['rename_to', 'start'],
|
||||
['rename_to', 'cache'],
|
||||
['rename_to', 'cycle'],
|
||||
['rename_to', 'cascade'],
|
||||
['rename_to', 'owner'],
|
||||
['rename_to', 'newschema'],
|
||||
['cascade', 'data_type'],
|
||||
['cascade', 'increment'],
|
||||
['cascade', 'minvalue'],
|
||||
['cascade', 'maxvalue'],
|
||||
['cascade', 'start'],
|
||||
['cascade', 'cache'],
|
||||
['cascade', 'cycle'],
|
||||
['cascade', 'owner'],
|
||||
['cascade', 'newschema'],
|
||||
]
|
||||
)
|
||||
|
||||
# Note: we don't need to check mutually exclusive params here, because they are
|
||||
# checked automatically by AnsibleModule (mutually_exclusive=[] list above).
|
||||
|
||||
# Change autocommit to False if check_mode:
|
||||
autocommit = not module.check_mode
|
||||
# Connect to DB and make cursor object:
|
||||
db_connection = connect_to_db(module, autocommit=autocommit)
|
||||
cursor = db_connection.cursor(cursor_factory=DictCursor)
|
||||
|
||||
##############
|
||||
# Create the object and do main job:
|
||||
data = Sequence(module, cursor)
|
||||
|
||||
# Set defaults:
|
||||
changed = False
|
||||
|
||||
# Create new sequence
|
||||
if not data.exists and module.params['state'] == 'present':
|
||||
if module.params.get('rename_to'):
|
||||
module.fail_json(msg="Sequence '%s' does not exist, nothing to rename" % module.params['sequence'])
|
||||
if module.params.get('newschema'):
|
||||
module.fail_json(msg="Sequence '%s' does not exist, change of schema not possible" % module.params['sequence'])
|
||||
|
||||
changed = data.create()
|
||||
|
||||
# Drop non-existing sequence
|
||||
elif not data.exists and module.params['state'] == 'absent':
|
||||
# Nothing to do
|
||||
changed = False
|
||||
|
||||
# Drop existing sequence
|
||||
elif data.exists and module.params['state'] == 'absent':
|
||||
changed = data.drop()
|
||||
|
||||
# Rename sequence
|
||||
if data.exists and module.params.get('rename_to'):
|
||||
if data.name != module.params['rename_to']:
|
||||
changed = data.rename()
|
||||
if changed:
|
||||
data.new_name = module.params['rename_to']
|
||||
|
||||
# Refresh information
|
||||
if module.params['state'] == 'present':
|
||||
data.get_info()
|
||||
|
||||
# Change owner, schema and settings
|
||||
if module.params['state'] == 'present' and data.exists:
|
||||
# change owner
|
||||
if module.params.get('owner'):
|
||||
if data.owner != module.params['owner']:
|
||||
changed = data.set_owner()
|
||||
|
||||
# Set schema
|
||||
if module.params.get('newschema'):
|
||||
if data.schema != module.params['newschema']:
|
||||
changed = data.set_schema()
|
||||
if changed:
|
||||
data.new_schema = module.params['newschema']
|
||||
|
||||
# Rollback if it's possible and check_mode:
|
||||
if module.check_mode:
|
||||
db_connection.rollback()
|
||||
else:
|
||||
db_connection.commit()
|
||||
|
||||
cursor.close()
|
||||
db_connection.close()
|
||||
|
||||
# Make return values:
|
||||
kw = dict(
|
||||
changed=changed,
|
||||
state='present',
|
||||
sequence=data.name,
|
||||
queries=data.executed_queries,
|
||||
schema=data.schema,
|
||||
data_type=data.data_type,
|
||||
increment=data.increment,
|
||||
minvalue=data.minvalue,
|
||||
maxvalue=data.maxvalue,
|
||||
start=data.start_value,
|
||||
cycle=data.cycle,
|
||||
owner=data.owner,
|
||||
)
|
||||
|
||||
if module.params['state'] == 'present':
|
||||
if data.new_name:
|
||||
kw['newname'] = data.new_name
|
||||
if data.new_schema:
|
||||
kw['newschema'] = data.new_schema
|
||||
|
||||
elif module.params['state'] == 'absent':
|
||||
kw['state'] = 'absent'
|
||||
|
||||
module.exit_json(**kw)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -837,6 +837,10 @@
|
|||
- include: postgresql_copy.yml
|
||||
when: postgres_version_resp.stdout is version('9.4', '>=')
|
||||
|
||||
# Test postgresql_sequence module
|
||||
- include: postgresql_sequence.yml
|
||||
when: postgres_version_resp.stdout is version('9.0', '>=')
|
||||
|
||||
# Test postgresql_ext.
|
||||
# pg_extension system view is available from PG 9.1.
|
||||
# The tests are restricted by Fedora because there will be errors related with
|
||||
|
|
|
@ -0,0 +1,696 @@
|
|||
# Copyright: (c) 2019, Tobias Birkefeld (@tcraxs) <t@craxs.de>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
# Preparation for tests.
|
||||
- name: postgresql_sequence - create DB
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_db:
|
||||
state: present
|
||||
name: "{{ db_name }}"
|
||||
owner: "{{ db_user1 }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
|
||||
- name: postgresql_sequence - create a user to be owner of a database
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_user:
|
||||
name: "{{ db_user1 }}"
|
||||
state: present
|
||||
encrypted: yes
|
||||
password: password
|
||||
role_attr_flags: LOGIN
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
|
||||
- name: Create a user to be owner of a sequence
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_user:
|
||||
name: "{{ db_user2 }}"
|
||||
state: present
|
||||
encrypted: yes
|
||||
password: password
|
||||
role_attr_flags: LOGIN
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
|
||||
- name: postgresql_sequence - create a schema
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_schema:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar_schema
|
||||
|
||||
####################
|
||||
# Test: create sequence in checkmode
|
||||
- name: postgresql_sequence - create a new seqeunce with name "foobar" in check_mode
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
check_mode: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar'
|
||||
- result.queries == ["CREATE SEQUENCE \"public\".\"foobar\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the new seqeunce "foobar" not exists
|
||||
become: yes
|
||||
become_user: "{{ pg_user }}"
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'foobar'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 0
|
||||
- result.statusmessage == 'SELECT 0'
|
||||
|
||||
####################
|
||||
# Test: create sequence
|
||||
- name: postgresql_sequence - create a new seqeunce with name "foobar"
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar'
|
||||
- result.queries == ["CREATE SEQUENCE \"public\".\"foobar\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the new seqeunce "foobar" exists
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'foobar'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
####################
|
||||
# Test: drop sequence in checkmode
|
||||
- name: postgresql_sequence - drop a sequence called foobar
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
check_mode: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar'
|
||||
- result.queries == ["DROP SEQUENCE \"public\".\"foobar\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the seqeunce "foobar" still exists
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'foobar'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
####################
|
||||
# Test: drop sequence
|
||||
- name: postgresql_sequence - drop a sequence called foobar
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar'
|
||||
- result.queries == ["DROP SEQUENCE \"public\".\"foobar\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the seqeunce "foobar" not exists
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'foobar'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 0
|
||||
|
||||
####################
|
||||
# Test: drop nonexistent sequence
|
||||
- name: postgresql_sequence - drop a sequence called foobar which does not exists
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == False
|
||||
- result.sequence == 'foobar'
|
||||
- result.queries == []
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the seqeunce "foobar" not exists
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'foobar'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 0
|
||||
|
||||
####################
|
||||
# Test: create sequence with options
|
||||
- name: postgresql_sequence - create an descending sequence called foobar_desc, starting at 101 and which cycle between 1 to 1000
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar_desc
|
||||
increment: -1
|
||||
start: 101
|
||||
minvalue: 1
|
||||
maxvalue: 1000
|
||||
cycle: yes
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar_desc'
|
||||
- result.increment == '-1'
|
||||
- result.minvalue == '1'
|
||||
- result.maxvalue == '1000'
|
||||
- result.cycle == 'YES'
|
||||
- result.queries == ["CREATE SEQUENCE \"public\".\"foobar_desc\" INCREMENT BY -1 MINVALUE 1 MAXVALUE 1000 START WITH 101 CYCLE"]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the new seqeunce "foobar_desc" exists
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'foobar_desc'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
####################
|
||||
# Test: rename a sequence in checkmode
|
||||
- name: postgresql_sequence - rename an existing sequence named foobar_desc to foobar_with_options
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
check_mode: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar_desc
|
||||
rename_to: foobar_with_options
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar_desc'
|
||||
- result.newname == 'foobar_with_options'
|
||||
- result.queries == ["ALTER SEQUENCE \"public\".\"foobar_desc\" RENAME TO \"foobar_with_options\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the seqeunce "foobar_desc" still exists and is not renamed
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'foobar_desc'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
####################
|
||||
# Test: rename a sequence
|
||||
- name: postgresql_sequence - rename an existing sequence named foobar_desc to foobar_with_options
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar_desc
|
||||
rename_to: foobar_with_options
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar_desc'
|
||||
- result.newname == 'foobar_with_options'
|
||||
- result.queries == ["ALTER SEQUENCE \"public\".\"foobar_desc\" RENAME TO \"foobar_with_options\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the renamed seqeunce "foobar_with_options" exists
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'foobar_with_options'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
####################
|
||||
# Test: change schema of a sequence in checkmode
|
||||
- name: postgresql_sequence - change schema of an existing sequence from public to foobar_schema
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
check_mode: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar_with_options
|
||||
newschema: foobar_schema
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar_with_options'
|
||||
- result.schema == 'public'
|
||||
- result.newschema == 'foobar_schema'
|
||||
- result.queries == ["ALTER SEQUENCE \"public\".\"foobar_with_options\" SET SCHEMA \"foobar_schema\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the seqeunce "foobar_with_options" still exists in the old schema
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name,sequence_schema FROM information_schema.sequences WHERE sequence_name = 'foobar_with_options' AND sequence_schema = 'public'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
####################
|
||||
# Test: change schema of a sequence
|
||||
- name: postgresql_sequence - change schema of an existing sequence from public to foobar_schema
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar_with_options
|
||||
newschema: foobar_schema
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar_with_options'
|
||||
- result.schema == 'public'
|
||||
- result.newschema == 'foobar_schema'
|
||||
- result.queries == ["ALTER SEQUENCE \"public\".\"foobar_with_options\" SET SCHEMA \"foobar_schema\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the seqeunce "foobar_with_options" exists in new schema
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name,sequence_schema FROM information_schema.sequences WHERE sequence_name = 'foobar_with_options' AND sequence_schema = 'foobar_schema'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
####################
|
||||
# Test: change owner of a sequence in checkmode
|
||||
- name: postgresql_sequence - change owner of an existing sequence from "{{ pg_user }}" to "{{ db_user1 }}"
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
check_mode: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar_with_options
|
||||
schema: foobar_schema
|
||||
owner: "{{ db_user1 }}"
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar_with_options'
|
||||
- result.owner == "{{ pg_user }}"
|
||||
- result.queries == ["ALTER SEQUENCE \"foobar_schema\".\"foobar_with_options\" OWNER TO \"{{ db_user1 }}\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the seqeunce "foobar_with_options" has still the old owner
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT c.relname,a.rolname,n.nspname
|
||||
FROM pg_class as c
|
||||
JOIN pg_authid as a on (c.relowner = a.oid)
|
||||
JOIN pg_namespace as n on (c.relnamespace = n.oid)
|
||||
WHERE c.relkind = 'S' and
|
||||
c.relname = 'foobar_with_options' and
|
||||
n.nspname = 'foobar_schema' and
|
||||
a.rolname = '{{ pg_user }}'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
####################
|
||||
# Test: change owner of a sequence
|
||||
- name: postgresql_sequence - change owner of an existing sequence from "{{ pg_user }}" to "{{ db_user1 }}"
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar_with_options
|
||||
schema: foobar_schema
|
||||
owner: "{{ db_user1 }}"
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar_with_options'
|
||||
- result.owner == "{{ pg_user }}"
|
||||
- result.queries == ["ALTER SEQUENCE \"foobar_schema\".\"foobar_with_options\" OWNER TO \"{{ db_user1 }}\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the seqeunce "foobar_with_options" has a new owner
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT c.relname,a.rolname,n.nspname
|
||||
FROM pg_class as c
|
||||
JOIN pg_authid as a on (c.relowner = a.oid)
|
||||
JOIN pg_namespace as n on (c.relnamespace = n.oid)
|
||||
WHERE c.relkind = 'S' and
|
||||
c.relname = 'foobar_with_options' and
|
||||
n.nspname = 'foobar_schema' and
|
||||
a.rolname = '{{ db_user1 }}'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
####################
|
||||
# Test: drop seqeunce with cascade
|
||||
|
||||
# CREATE SEQUENCE seq1;
|
||||
# CREATE TABLE t1 (f1 INT NOT NULL DEFAULT nextval('seq1'));
|
||||
# DROP SEQUENCE seq1 CASCADE;
|
||||
- name: postgresql_sequence - create sequence for drop cascade test
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: seq1
|
||||
|
||||
- name: postgresql_sequence - create table which use seqeunce for drop cascade test
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_table:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: t1
|
||||
columns:
|
||||
- f1 INT NOT NULL DEFAULT nextval('seq1')
|
||||
|
||||
####################
|
||||
# Test: drop seqeunce with cascade in checkmode
|
||||
- name: postgresql_sequence - drop with cascade a sequence called seq1
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
check_mode: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: seq1
|
||||
state: absent
|
||||
cascade: yes
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'seq1'
|
||||
- result.queries == ["DROP SEQUENCE \"public\".\"seq1\" CASCADE"]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the seqeunce "seq1" still exists
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'seq1'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
####################
|
||||
# Test: drop seqeunce with cascade
|
||||
- name: postgresql_sequence - drop with cascade a sequence called seq1
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: seq1
|
||||
state: absent
|
||||
cascade: yes
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'seq1'
|
||||
- result.queries == ["DROP SEQUENCE \"public\".\"seq1\" CASCADE"]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the seqeunce "seq1" not exists
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'seq1'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 0
|
||||
|
||||
####################
|
||||
# Test: create sequence with owner in checkmode
|
||||
- name: postgresql_sequence - create a new seqeunce with name "foobar2" with owner "{{ db_user2 }}"
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
check_mode: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar2
|
||||
owner: "{{ db_user2 }}"
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar2'
|
||||
- result.queries == ["CREATE SEQUENCE \"public\".\"foobar2\"", "ALTER SEQUENCE \"public\".\"foobar2\" OWNER TO \"ansible_db_user2\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the new seqeunce "foobar2" does not exists
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'foobar2'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 0
|
||||
|
||||
####################
|
||||
# Test: create sequence with owner
|
||||
- name: postgresql_sequence - create a new seqeunce with name "foobar2" with owner "{{ db_user2 }}"
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_sequence:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
name: foobar2
|
||||
owner: "{{ db_user2 }}"
|
||||
register: result
|
||||
|
||||
# Checks
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.changed == True
|
||||
- result.sequence == 'foobar2'
|
||||
- result.queries == ["CREATE SEQUENCE \"public\".\"foobar2\"", "ALTER SEQUENCE \"public\".\"foobar2\" OWNER TO \"ansible_db_user2\""]
|
||||
|
||||
# Real SQL check
|
||||
- name: postgresql_sequence - check that the new seqeunce "foobar2" exists
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT sequence_name FROM information_schema.sequences WHERE sequence_name = 'foobar2'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
- name: postgresql_sequence - check that the seqeunce "foobar2" has owner "{{ db_user2 }}"
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_query:
|
||||
db: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
||||
query: "SELECT c.relname,a.rolname,n.nspname
|
||||
FROM pg_class as c
|
||||
JOIN pg_authid as a on (c.relowner = a.oid)
|
||||
JOIN pg_namespace as n on (c.relnamespace = n.oid)
|
||||
WHERE c.relkind = 'S' and
|
||||
c.relname = 'foobar2' and
|
||||
n.nspname = 'public' and
|
||||
a.rolname = '{{ db_user2 }}'"
|
||||
register: result
|
||||
|
||||
- name: postgresql_sequence - check with assert the output
|
||||
assert:
|
||||
that:
|
||||
- result.rowcount == 1
|
||||
|
||||
# Cleanup
|
||||
- name: postgresql_sequence - destroy DB
|
||||
become_user: "{{ pg_user }}"
|
||||
become: yes
|
||||
postgresql_db:
|
||||
state: absent
|
||||
name: "{{ db_name }}"
|
||||
login_user: "{{ pg_user }}"
|
Loading…
Reference in a new issue