ansible-later/env_27/lib/python2.7/site-packages/ansible/modules/notification/snow_record.py
2019-04-11 13:00:36 +02:00

333 lines
10 KiB
Python

#!/usr/bin/python
# Copyright (c) 2017 Tim Rightnour <thegarbledone@gmail.com>
# 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 = '''
---
module: snow_record
short_description: Create/Delete/Update records in ServiceNow
version_added: "2.5"
description:
- Creates/Deletes/Updates a single record in ServiceNow
options:
instance:
description:
- The service now instance name
required: true
username:
description:
- User to connect to ServiceNow as
required: true
password:
description:
- Password for username
required: true
table:
description:
- Table to query for records
required: false
default: incident
state:
description:
- If C(present) is supplied with a C(number)
argument, the module will attempt to update the record with
the supplied data. If no such record exists, a new one will
be created. C(absent) will delete a record.
choices: [ present, absent ]
required: true
data:
description:
- key, value pairs of data to load into the record.
See Examples. Required for C(state:present)
number:
description:
- Record number to update. Required for C(state:absent)
required: false
lookup_field:
description:
- Changes the field that C(number) uses to find records
required: false
default: number
attachment:
description:
- Attach a file to the record
required: false
requirements:
- python pysnow (pysnow)
author:
- Tim Rightnour (@garbled1)
'''
EXAMPLES = '''
- name: Grab a user record
snow_record:
username: ansible_test
password: my_password
instance: dev99999
state: present
number: 62826bf03710200044e0bfc8bcbe5df1
table: sys_user
lookup_field: sys_id
- name: Create an incident
snow_record:
username: ansible_test
password: my_password
instance: dev99999
state: present
data:
short_description: "This is a test incident opened by Ansible"
severity: 3
priority: 2
register: new_incident
- name: Delete the record we just made
snow_record:
username: admin
password: xxxxxxx
instance: dev99999
state: absent
number: "{{new_incident['record']['number']}}"
- name: Delete a non-existant record
snow_record:
username: ansible_test
password: my_password
instance: dev99999
state: absent
number: 9872354
failed_when: false
- name: Update an incident
snow_record:
username: ansible_test
password: my_password
instance: dev99999
state: present
number: INC0000055
data:
work_notes : "Been working all day on this thing."
- name: Attach a file to an incident
snow_record:
username: ansible_test
password: my_password
instance: dev99999
state: present
number: INC0000055
attachment: README.md
tags: attach
'''
RETURN = '''
record:
description: Record data from Service Now
type: dict
returned: when supported
attached_file:
description: Details of the file that was attached via C(attachment)
type: dict
returned: when supported
'''
import os
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_bytes, to_native
# Pull in pysnow
HAS_PYSNOW = False
try:
import pysnow
HAS_PYSNOW = True
except ImportError:
pass
def run_module():
# define the available arguments/parameters that a user can pass to
# the module
module_args = dict(
instance=dict(default=None, type='str', required=True),
username=dict(default=None, type='str', required=True, no_log=True),
password=dict(default=None, type='str', required=True, no_log=True),
table=dict(type='str', required=False, default='incident'),
state=dict(choices=['present', 'absent'],
type='str', required=True),
number=dict(default=None, required=False, type='str'),
data=dict(default=None, required=False, type='dict'),
lookup_field=dict(default='number', required=False, type='str'),
attachment=dict(default=None, required=False, type='str')
)
module_required_if = [
['state', 'absent', ['number']],
]
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True,
required_if=module_required_if
)
# check for pysnow
if not HAS_PYSNOW:
module.fail_json(msg='pysnow module required')
params = module.params
instance = params['instance']
username = params['username']
password = params['password']
table = params['table']
state = params['state']
number = params['number']
data = params['data']
lookup_field = params['lookup_field']
result = dict(
changed=False,
instance=instance,
table=table,
number=number,
lookup_field=lookup_field
)
# check for attachments
if params['attachment'] is not None:
attach = params['attachment']
b_attach = to_bytes(attach, errors='surrogate_or_strict')
if not os.path.exists(b_attach):
module.fail_json(msg="Attachment {0} not found".format(attach))
result['attachment'] = attach
else:
attach = None
# Connect to ServiceNow
try:
conn = pysnow.Client(instance=instance, user=username,
password=password)
except Exception as detail:
module.fail_json(msg='Could not connect to ServiceNow: {0}'.format(str(detail)), **result)
# Deal with check mode
if module.check_mode:
# if we are in check mode and have no number, we would have created
# a record. We can only partially simulate this
if number is None:
result['record'] = dict(data)
result['changed'] = True
# do we want to check if the record is non-existent?
elif state == 'absent':
try:
record = conn.query(table=table, query={lookup_field: number})
res = record.get_one()
result['record'] = dict(Success=True)
result['changed'] = True
except pysnow.exceptions.NoResults:
result['record'] = None
except Exception as detail:
module.fail_json(msg="Unknown failure in query record: {0}".format(str(detail)), **result)
# Let's simulate modification
else:
try:
record = conn.query(table=table, query={lookup_field: number})
res = record.get_one()
for key, value in data.items():
res[key] = value
result['changed'] = True
result['record'] = res
except pysnow.exceptions.NoResults:
snow_error = "Record does not exist"
module.fail_json(msg=snow_error, **result)
except Exception as detail:
module.fail_json(msg="Unknown failure in query record: {0}".format(str(detail)), **result)
module.exit_json(**result)
# now for the real thing: (non-check mode)
# are we creating a new record?
if state == 'present' and number is None:
try:
record = conn.insert(table=table, payload=dict(data))
except pysnow.UnexpectedResponse as e:
snow_error = "Failed to create record: {0}, details: {1}".format(e.error_summary, e.error_details)
module.fail_json(msg=snow_error, **result)
result['record'] = record
result['changed'] = True
# we are deleting a record
elif state == 'absent':
try:
record = conn.query(table=table, query={lookup_field: number})
res = record.delete()
except pysnow.exceptions.NoResults:
res = dict(Success=True)
except pysnow.exceptions.MultipleResults:
snow_error = "Multiple record match"
module.fail_json(msg=snow_error, **result)
except pysnow.UnexpectedResponse as e:
snow_error = "Failed to delete record: {0}, details: {1}".format(e.error_summary, e.error_details)
module.fail_json(msg=snow_error, **result)
except Exception as detail:
snow_error = "Failed to delete record: {0}".format(str(detail))
module.fail_json(msg=snow_error, **result)
result['record'] = res
result['changed'] = True
# We want to update a record
else:
try:
record = conn.query(table=table, query={lookup_field: number})
if data is not None:
res = record.update(dict(data))
result['record'] = res
result['changed'] = True
else:
res = record.get_one()
result['record'] = res
if attach is not None:
res = record.attach(b_attach)
result['changed'] = True
result['attached_file'] = res
except pysnow.exceptions.MultipleResults:
snow_error = "Multiple record match"
module.fail_json(msg=snow_error, **result)
except pysnow.exceptions.NoResults:
snow_error = "Record does not exist"
module.fail_json(msg=snow_error, **result)
except pysnow.UnexpectedResponse as e:
snow_error = "Failed to update record: {0}, details: {1}".format(e.error_summary, e.error_details)
module.fail_json(msg=snow_error, **result)
except Exception as detail:
snow_error = "Failed to update record: {0}".format(str(detail))
module.fail_json(msg=snow_error, **result)
module.exit_json(**result)
def main():
run_module()
if __name__ == '__main__':
main()