summaryrefslogtreecommitdiffstats
path: root/collections-debian-merged/ansible_collections/servicenow
diff options
context:
space:
mode:
Diffstat (limited to 'collections-debian-merged/ansible_collections/servicenow')
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/.github/workflows/ansible-test.yml51
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/.github/workflows/galaxy-release.yml31
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/.gitignore394
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/CHANGELOG.rst36
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/FILES.json320
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/MANIFEST.json40
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/README.md93
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/.plugin-cache.yaml29
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/changelog.yaml29
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/config.yaml32
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/fragments/.keep0
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/config/now.yml.sample5
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/docs/create_docs.yml28
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/docs/inventory.md170
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/docs/snow_record.md156
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/docs/snow_record_find.md131
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/docs/templates/docs.md.j238
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/meta/runtime.yml2
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/doc_fragments/service_now.py50
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/inventory/now.py316
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/module_utils/service_now.py99
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/modules/snow_record.py387
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/modules/snow_record_find.py318
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/requirements.txt2
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/tests/enhanced.now.yml10
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/tests/module_test.yml36
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/tests/module_test_cmdb_ci_server.yml220
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/tests/network.enhanced.now.yml8
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/tests/now.yml26
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/update_sets/README.md5
-rw-r--r--collections-debian-merged/ansible_collections/servicenow/servicenow/update_sets/ansible_enhanced_inventory.xml219
31 files changed, 3281 insertions, 0 deletions
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/.github/workflows/ansible-test.yml b/collections-debian-merged/ansible_collections/servicenow/servicenow/.github/workflows/ansible-test.yml
new file mode 100644
index 00000000..70a87e12
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/.github/workflows/ansible-test.yml
@@ -0,0 +1,51 @@
+name: CI
+on:
+# Run CI against all pushes (direct commits) and Pull Requests
+- push
+- pull_request
+
+jobs:
+
+###
+# Sanity tests (REQUIRED)
+#
+# https://docs.ansible.com/ansible/latest/dev_guide/testing_sanity.html
+
+ sanity:
+ name: Sanity (Ⓐ${{ matrix.ansible }}+py${{ matrix.python }})
+ strategy:
+ matrix:
+ ansible:
+ # It's important that Sanity is tested against all stable-X.Y branches
+ # Testing against `devel` may fail as new tests are added.
+ - stable-2.9 # Only if your collection supports Ansible 2.9
+ - stable-2.10
+ - devel
+ python:
+ - 2.7
+ - 3.7
+ - 3.8
+ exclude:
+ - python: 3.8 # blocked by ansible/ansible#70155
+ runs-on: ubuntu-latest
+ steps:
+
+ - name: Check out code
+ uses: actions/checkout@v1
+ with:
+ path: ansible_collections/servicenow/servicenow
+
+ - name: Set up Python ${{ matrix.ansible }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python }}
+
+ # Install the head of the given branch (devel, stable-2.10)
+ - name: Install ansible-base (${{ matrix.ansible }})
+ run: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz --disable-pip-version-check
+
+ # run ansible-test sanity inside of Docker.
+ # The docker container has all the pinned dependencies that are required.
+ # Explicity specify the version of Python we want to test
+ - name: Run sanity tests
+ run: ansible-test sanity --docker -v --color --python ${{ matrix.python }}
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/.github/workflows/galaxy-release.yml b/collections-debian-merged/ansible_collections/servicenow/servicenow/.github/workflows/galaxy-release.yml
new file mode 100644
index 00000000..64614c50
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/.github/workflows/galaxy-release.yml
@@ -0,0 +1,31 @@
+---
+name: galaxy-release
+on:
+ release:
+ types:
+ - published
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ env:
+ ANSIBLE_FORCE_COLOR: 1
+ steps:
+ - name: Check out code
+ uses: actions/checkout@v1
+
+ - name: Set up Python 3.8
+ uses: actions/setup-python@v1
+ with:
+ python-version: 3.8
+
+ - name: Install ansible-base
+ run: pip install ansible
+
+ - name: Publish to galaxy
+ run: ansible-playbook release.yml
+ -e namespace=${{ github.repository_owner }}
+ -e github_tag=${{ github.ref }}
+ -e api_key=${{ secrets.ANSIBLE_GALAXY_APIKEY }}
+ -e collection_repo=https://github.com/${{ github.repository }}
+ --skip-tags=install,cleanup
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/.gitignore b/collections-debian-merged/ansible_collections/servicenow/servicenow/.gitignore
new file mode 100644
index 00000000..336766e0
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/.gitignore
@@ -0,0 +1,394 @@
+# Mac Junk
+.DS_Store
+
+#Ansible artifacts
+tests/output
+*.tar.gz
+galaxy.yml
+
+# Created by https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
+# Edit at https://www.gitignore.io/?templates=git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
+
+### dotenv ###
+.env
+
+### Emacs ###
+# -*- mode: gitignore; -*-
+*~
+\#*\#
+/.emacs.desktop
+/.emacs.desktop.lock
+*.elc
+auto-save-list
+tramp
+.\#*
+
+# Org-mode
+.org-id-locations
+*_archive
+
+# flymake-mode
+*_flymake.*
+
+# eshell files
+/eshell/history
+/eshell/lastdir
+
+# elpa packages
+/elpa/
+
+# reftex files
+*.rel
+
+# AUCTeX auto folder
+/auto/
+
+# cask packages
+.cask/
+dist/
+
+# Flycheck
+flycheck_*.el
+
+# server auth directory
+/server/
+
+# projectiles files
+.projectile
+
+# directory configuration
+.dir-locals.el
+
+# network security
+/network-security.data
+
+
+### Git ###
+# Created by git for backups. To disable backups in Git:
+# $ git config --global mergetool.keepBackup false
+*.orig
+
+# Created by git when using merge tools for conflicts
+*.BACKUP.*
+*.BASE.*
+*.LOCAL.*
+*.REMOTE.*
+*_BACKUP_*.txt
+*_BASE_*.txt
+*_LOCAL_*.txt
+*_REMOTE_*.txt
+
+#!! ERROR: jupyternotebook is undefined. Use list command to see defined gitignore types !!#
+
+### Linux ###
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### PyCharm+all ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### PyCharm+all Patch ###
+# Ignores the whole .idea folder and all .iml files
+# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
+
+.idea/
+
+# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
+
+*.iml
+modules.xml
+.idea/misc.xml
+*.ipr
+
+# Sonarlint plugin
+.idea/sonarlint
+
+### pydev ###
+.pydevproject
+
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# pyenv
+.python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# celery beat schedule file
+celerybeat-schedule
+
+# SageMath parsed files
+*.sage.py
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# Mr Developer
+.mr.developer.cfg
+.project
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+### Vim ###
+# Swap
+[._]*.s[a-v][a-z]
+[._]*.sw[a-p]
+[._]s[a-rt-v][a-z]
+[._]ss[a-gi-z]
+[._]sw[a-p]
+
+# Session
+Session.vim
+Sessionx.vim
+
+# Temporary
+.netrwhist
+# Auto-generated tag files
+tags
+# Persistent undo
+[._]*.un~
+
+### WebStorm ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+
+# Generated files
+
+# Sensitive or high-churn files
+
+# Gradle
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+
+# Mongo Explorer plugin
+
+# File-based project format
+
+# IntelliJ
+
+# mpeltonen/sbt-idea plugin
+
+# JIRA plugin
+
+# Cursive Clojure plugin
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+
+# Editor-based Rest Client
+
+# Android studio 3.1+ serialized cache file
+
+### WebStorm Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+.idea/**/sonarlint/
+
+# SonarQube Plugin
+.idea/**/sonarIssues.xml
+
+# Markdown Navigator plugin
+.idea/**/markdown-navigator.xml
+.idea/**/markdown-navigator/
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# End of https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/CHANGELOG.rst b/collections-debian-merged/ansible_collections/servicenow/servicenow/CHANGELOG.rst
new file mode 100644
index 00000000..e500b0de
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/CHANGELOG.rst
@@ -0,0 +1,36 @@
+===================================
+Servicenow.Servicenow Release Notes
+===================================
+
+.. contents:: Topics
+
+
+v1.0.4
+======
+
+Major Changes
+-------------
+
+- add new tests (find with no result, search many)
+- add related tests
+- add support for ServiceNOW table api display_value exclude_reference_link and suppress_pagination_header
+- use new API for pysnow >=0.6.0
+
+v1.0.3
+======
+
+Release Summary
+---------------
+
+use consistent auth parameters across plugins and modules
+
+Minor Changes
+-------------
+
+- adds the ability to use `SN_INSTANCE` (ex. `dev61775`) or `SN_HOST` (ex. `dev61775.service-now.com`) with the inventory plugin.
+
+Bugfixes
+--------
+
+- fix inventory plugin transforming hostnames unnecessarily
+- fix malformed documentation on docs.ansible.com
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/FILES.json b/collections-debian-merged/ansible_collections/servicenow/servicenow/FILES.json
new file mode 100644
index 00000000..072f16f4
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/FILES.json
@@ -0,0 +1,320 @@
+{
+ "files": [
+ {
+ "name": ".",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "config",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "config/now.yml.sample",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "606cea64ee0670f91c9f9c4d5f0bb96a6d78e649c97339ea8397194e2ac630d5",
+ "format": 1
+ },
+ {
+ "name": ".github",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": ".github/workflows",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": ".github/workflows/galaxy-release.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "bc82e07b7d94027d17753d366917193d3b75f09ba96b77662c5c8ae08584b50d",
+ "format": 1
+ },
+ {
+ "name": ".github/workflows/ansible-test.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "7edfb7837997796db09c6755dfc60bdbbb3371e6b6af269e344d6e5173053bfe",
+ "format": 1
+ },
+ {
+ "name": "CHANGELOG.rst",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "5787d890fecad4674e224601c31222f0389e3bb907d6c74783692795eca207aa",
+ "format": 1
+ },
+ {
+ "name": "meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "meta/runtime.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "48a2f61c72296aaa190a3ad670b0a5759bd047262b59b3d870e986b05878d87d",
+ "format": 1
+ },
+ {
+ "name": "docs",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "docs/templates",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "docs/templates/docs.md.j2",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "8431b9f9430d6d0c1154dde567e2406cfe0e2526449740cc7014f7b2df3c8fbb",
+ "format": 1
+ },
+ {
+ "name": "docs/inventory.md",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "4fa69a805fd91aafea36f2672677d3319c9c6a25b39e2bd03684172bb8c2f6fc",
+ "format": 1
+ },
+ {
+ "name": "docs/snow_record_find.md",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "03197238ab13b8a897e5d7612f08f7ae55ad1cedf7a6507758a1a6b07cd4349e",
+ "format": 1
+ },
+ {
+ "name": "docs/snow_record.md",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "07643b41e054a048c7ac8cfeb6fc72bfa5e8c60065a8f2b7d961423c6dbcc2d5",
+ "format": 1
+ },
+ {
+ "name": "docs/create_docs.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e7e7588a0b59e2e5b7512a19ec6133fc96bf5aac68b87eb869b225b6cb767364",
+ "format": 1
+ },
+ {
+ "name": "tests",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/now.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "3914964e05a01859050ec3a5062cd6609aa381228de274a191656bb6cd146b63",
+ "format": 1
+ },
+ {
+ "name": "tests/module_test.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a2aecb71b1e36d9d03aeaab570664c9b0f0a98c192caef294d35f2b2865ade8a",
+ "format": 1
+ },
+ {
+ "name": "tests/enhanced.now.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ee1ac7151369516c6016ccb9b66ea6574ee3c71e34d8f4269c9cffc1cab20ebe",
+ "format": 1
+ },
+ {
+ "name": "tests/network.enhanced.now.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b761770cbf0844ef603fd11d7b9b4da06dacc15416a41630c12d5d8ca384216a",
+ "format": 1
+ },
+ {
+ "name": "tests/module_test_cmdb_ci_server.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f16a3e9b0e7eee38917c9681bd471dea9d11e15f275bd0ce6deb7f6fd37cb199",
+ "format": 1
+ },
+ {
+ "name": "update_sets",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "update_sets/ansible_enhanced_inventory.xml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "7ba14302626a267df368fad993c7b784d9b8398a9091a54192902c34afd18b61",
+ "format": 1
+ },
+ {
+ "name": "update_sets/README.md",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "d047f003c705cdb793cad679fe0da9fcca63a6d326d570172525aac134c8df54",
+ "format": 1
+ },
+ {
+ "name": "plugins",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/doc_fragments",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/doc_fragments/service_now.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "df633dfdeca0822cc25d6d9e4ed85ce84e0cf725cd0b1eb35c77437ed925c466",
+ "format": 1
+ },
+ {
+ "name": "plugins/inventory",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/inventory/now.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "78e9d17cd73456a7951736dafdd79705f3260e02e2d9e85d64b35565fc11f306",
+ "format": 1
+ },
+ {
+ "name": "plugins/module_utils",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/module_utils/service_now.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "448aa9dd05b9e927890c199bddd3ea85aa59c30468d28a817151a6efb58979f3",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/snow_record_find.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "5cc0f5513b09ab0746ad83ef419449c4399b4dbea118378ccdff18f85dd44f1a",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/snow_record.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "31c6dbd741d69da49c2d958a38b9121691f91ff14adafc0a7d2e2afffc04d7d6",
+ "format": 1
+ },
+ {
+ "name": "README.md",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "830b90abbfe0cf65c38f0b85713f55313e799ff39a2f566b7cce3e1f6f7d4bdf",
+ "format": 1
+ },
+ {
+ "name": ".gitignore",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "afd19f3a546e4f7c923914f5f9e7c0fb0c17680a00b63f73b2720fa56ec9e7b4",
+ "format": 1
+ },
+ {
+ "name": "changelogs",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "changelogs/.plugin-cache.yaml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ee7076ee32a338d6b4f79b738fd41d93c4a74816e21c39d02d8193670a8fd47a",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/.keep",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "format": 1
+ },
+ {
+ "name": "changelogs/config.yaml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b6f36b2c363e4e2764cecdbfeee2be02fa4d9704b0d132d426918358f708a2bf",
+ "format": 1
+ },
+ {
+ "name": "changelogs/changelog.yaml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6367c874144d392e40c44eee71b4f6d235e7bee24bc82e89c271b4160cfe1214",
+ "format": 1
+ },
+ {
+ "name": "requirements.txt",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "447a636d781f1d0dc043a0e3eafdc9a73fad67e68e6bd5a9ad6ebf003ae365e6",
+ "format": 1
+ }
+ ],
+ "format": 1
+} \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/MANIFEST.json b/collections-debian-merged/ansible_collections/servicenow/servicenow/MANIFEST.json
new file mode 100644
index 00000000..fbaff245
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/MANIFEST.json
@@ -0,0 +1,40 @@
+{
+ "collection_info": {
+ "namespace": "servicenow",
+ "name": "servicenow",
+ "version": "1.0.4",
+ "authors": [
+ "Paul Knight <paul.knight@delaware.gov>",
+ "Tim Rightnour <thegarbledone@gmail.com>",
+ "Will Tome (@willtome)",
+ "Alex Mittell (@alex_mittell)"
+ ],
+ "readme": "README.md",
+ "tags": [
+ "preview",
+ "servicenow",
+ "snow",
+ "collection",
+ "inventory",
+ "plugin"
+ ],
+ "description": "The Service Now modules previously packaged as part of Ansible, now in a Collection distributed via Ansible Galaxy. snow_record creates, updates or deletes a record in a specified table in the Service Now instance. snow_record_find retrieves one or more records based on the supplied query. ServiceNow Inventory Plugin for using ServiceNow CMDB as a dynamic inventory source.\n",
+ "license": [
+ "GPL-3.0-or-later"
+ ],
+ "license_file": null,
+ "dependencies": {},
+ "repository": "https://github.com/ServiceNowITOM/servicenow-ansible",
+ "documentation": "https://github.com/ServiceNowITOM/servicenow-ansible/wiki",
+ "homepage": "https://github.com/ServiceNowITOM/servicenow-ansible",
+ "issues": "https://github.com/ServiceNowITOM/servicenow-ansible/issues"
+ },
+ "file_manifest_file": {
+ "name": "FILES.json",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e0f0bc81456475e1de90a90122535407bfe446587c0cae9e9e20bfe7308a86cf",
+ "format": 1
+ },
+ "format": 1
+} \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/README.md b/collections-debian-merged/ansible_collections/servicenow/servicenow/README.md
new file mode 100644
index 00000000..071d4b08
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/README.md
@@ -0,0 +1,93 @@
+![CI](https://github.com/ServiceNowITOM/servicenow-ansible/workflows/CI/badge.svg)
+
+# Ansible Collection for ServiceNow
+This collection provides a series of Ansible modules, roles, and plugins for interacting with [ServiceNow](https://servicenow.com)
+
+## Requirements
+ - ansible version >= 2.9
+ - pysnow
+ - netaddr
+
+## Installation
+
+To install ServiceNow collection hosted in Galaxy:
+
+```bash
+ansible-galaxy collection install servicenow.servicenow
+```
+
+To upgrade to the latest version of ServiceNow collection:
+
+```bash
+ansible-galaxy collection install servicenow.servicenow --force
+```
+## Usage
+
+### Playbooks
+
+To use a module from the ServiceNow collection, please reference the fill namespace, collection name, and module name that you want to use:
+
+```yaml
+---
+- name: Using ServiceNow Collection
+ hosts: localhost
+ gather_facts: no
+
+ tasks:
+ - name: Create an incident
+ servicenow.servicenow.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
+```
+
+Or you can add full namespace and collection name in the `collections` section:
+
+```yaml
+---
+- name: Using ServiceNow Collection
+ hosts: localhost
+ gather_facts: no
+ collections:
+ - servicenow.servicenow
+
+ tasks:
+ - 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
+```
+
+### Roles
+
+For existing Ansible roles, please also reference the full namespace, collection name, and modules name which used in tasks instead of just modules name.
+
+## Resource Included
+
+### Modules
+- [snow_record](docs/snow_record.md) - Creates, deletes and updates a single record in ServiceNow.
+- [snow_record_find](docs/snow_record_find.md) - Gets multiple records from a specified table from ServiceNow based on a query dictionary.
+
+### Plugins
+- [now](docs/inventory.md) - ServiceNow Inventory Plugin
+
+## Contributing
+
+There are many ways in which you can participate in the project, for example:
+
+- Submit bugs and feature requests, and help us verify as they are checked in
+- Review source code changes
+- Review the documentation and make pull requests for anything from typos to new content
+
+Special thanks to Tim Rightnour (@garbled1) for the original version of ServiceNow modules in Ansible Core.
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/.plugin-cache.yaml b/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/.plugin-cache.yaml
new file mode 100644
index 00000000..fbb1bf38
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/.plugin-cache.yaml
@@ -0,0 +1,29 @@
+plugins:
+ become: {}
+ cache: {}
+ callback: {}
+ cliconf: {}
+ connection: {}
+ httpapi: {}
+ inventory:
+ now:
+ description: ServiceNow Inventory Plugin
+ name: now
+ version_added: '2.10'
+ lookup: {}
+ module:
+ snow_record:
+ description: Manage records in ServiceNow
+ name: snow_record
+ namespace: ''
+ version_added: null
+ snow_record_find:
+ description: Search for multiple records from ServiceNow
+ name: snow_record_find
+ namespace: ''
+ version_added: null
+ netconf: {}
+ shell: {}
+ strategy: {}
+ vars: {}
+version: 1.0.4
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/changelog.yaml b/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/changelog.yaml
new file mode 100644
index 00000000..cd39a5b6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/changelog.yaml
@@ -0,0 +1,29 @@
+ancestor: null
+releases:
+ 1.0.3:
+ changes:
+ bugfixes:
+ - fix inventory plugin transforming hostnames unnecessarily
+ - fix malformed documentation on docs.ansible.com
+ minor_changes:
+ - adds the ability to use `SN_INSTANCE` (ex. `dev61775`) or `SN_HOST` (ex. `dev61775.service-now.com`)
+ with the inventory plugin.
+ release_summary: use consistent auth parameters across plugins and modules
+ fragments:
+ - 1.0.3_release_summary.yml
+ - 17_auth_consistency.yml
+ - 22_hostnames.yml
+ - 29_documentation.yml
+ release_date: '2020-10-30'
+ 1.0.4:
+ changes:
+ major_changes:
+ - add new tests (find with no result, search many)
+ - add related tests
+ - add support for ServiceNOW table api display_value exclude_reference_link
+ and suppress_pagination_header
+ - use new API for pysnow >=0.6.0
+ fragments:
+ - 34_pysnow_0.6.yml
+ - 35_add_new_parameters.yml
+ release_date: '2021-02-03'
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/config.yaml b/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/config.yaml
new file mode 100644
index 00000000..408156ea
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/config.yaml
@@ -0,0 +1,32 @@
+changelog_filename_template: ../CHANGELOG.rst
+changelog_filename_version_depth: 0
+changes_file: changelog.yaml
+changes_format: combined
+ignore_other_fragment_extensions: true
+keep_fragments: false
+mention_ancestor: true
+new_plugins_after_name: removed_features
+notesdir: fragments
+prelude_section_name: release_summary
+prelude_section_title: Release Summary
+sanitize_changelog: true
+sections:
+- - major_changes
+ - Major Changes
+- - minor_changes
+ - Minor Changes
+- - breaking_changes
+ - Breaking Changes / Porting Guide
+- - deprecated_features
+ - Deprecated Features
+- - removed_features
+ - Removed Features (previously deprecated)
+- - security_fixes
+ - Security Fixes
+- - bugfixes
+ - Bugfixes
+- - known_issues
+ - Known Issues
+title: Servicenow.Servicenow
+trivial_section_name: trivial
+use_fqcn: true
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/fragments/.keep b/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/fragments/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/changelogs/fragments/.keep
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/config/now.yml.sample b/collections-debian-merged/ansible_collections/servicenow/servicenow/config/now.yml.sample
new file mode 100644
index 00000000..103b2df9
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/config/now.yml.sample
@@ -0,0 +1,5 @@
+plugin: servicenow.servicenow.now
+instance: demo.service-now.com
+username: admin
+password: password
+cache: True
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/create_docs.yml b/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/create_docs.yml
new file mode 100644
index 00000000..586137a9
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/create_docs.yml
@@ -0,0 +1,28 @@
+---
+- hosts: localhost
+ gather_facts: no
+
+ tasks:
+ - set_fact:
+ docs: "{{ lookup('file', '../plugins/inventory/now.py') | regex_search(\"(?<=DOCUMENTATION\\s=\\s''')((.|\\n)*?)(?=''')\") | from_yaml}}"
+ examples: "{{ lookup('file', '../plugins/inventory/now.py') | regex_search(\"(?<=EXAMPLES\\s=\\s''')((.|\\n)*?)(?=''')\") }}"
+
+ - template:
+ src: ./templates/docs.md.j2
+ dest: ./inventory.md
+
+ - set_fact:
+ docs: "{{ lookup('file', '../plugins/modules/snow_record.py') | regex_search(\"(?<=DOCUMENTATION\\s=\\s''')((.|\\n)*?)(?=''')\") | from_yaml}}"
+ examples: "{{ lookup('file', '../plugins/modules/snow_record.py') | regex_search(\"(?<=EXAMPLES\\s=\\s''')((.|\\n)*?)(?=''')\") }}"
+
+ - template:
+ src: ./templates/docs.md.j2
+ dest: ./snow_record.md
+
+ - set_fact:
+ docs: "{{ lookup('file', '../plugins/modules/snow_record_find.py') | regex_search(\"(?<=DOCUMENTATION\\s=\\s''')((.|\\n)*?)(?=''')\") | from_yaml}}"
+ examples: "{{ lookup('file', '../plugins/modules/snow_record_find.py') | regex_search(\"(?<=EXAMPLES\\s=\\s''')((.|\\n)*?)(?=''')\") }}"
+
+ - template:
+ src: ./templates/docs.md.j2
+ dest: ./snow_record_find.md \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/inventory.md b/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/inventory.md
new file mode 100644
index 00000000..64cc4924
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/inventory.md
@@ -0,0 +1,170 @@
+servicenow.servicenow.now - ServiceNow Inventory Plugin
+====================================
+- [Synopsis](Synopsis)
+- [Requirements](Requirements)
+- [Parameters](Parameters)
+- [Examples](Examples)
+
+## Synopsis
+- ServiceNow Inventory plugin
+
+## Requirements
+- requests
+- netaddr
+
+## Parameters
+
+<table>
+<tr>
+<th> Parameter </th>
+<th> Choices/Defaults </th>
+<th> Configuration </th>
+<th> Comments </th>
+</tr>
+<tr>
+<td><b>username</b></br>
+</td>
+<td></td>
+<td><b>env:</b><br>
+- name: SN_USERNAME
+</td>
+<td> Name of user for connection to ServiceNow. If the value is not specified, the value of environment variable C(SN_USERNAME) will be used instead. </td>
+</tr>
+<tr>
+<td><b>plugin</b></br>
+<p style="color:red;font-size:75%">required</p></td>
+<td><b>Choices:</b><br>
+- servicenow.servicenow.now
+</td>
+<td></td>
+<td> The name of the ServiceNow Inventory Plugin, this should always be 'servicenow.servicenow.now'. </td>
+</tr>
+<tr>
+<td><b>fields</b></br>
+</td>
+<td><b>Default:</b><br>
+ip_address,fqdn,host_name,sys_class_name,name</td>
+<td></td>
+<td> Comma seperated string providing additional table columns to add as host vars to each inventory host. </td>
+</tr>
+<tr>
+<td><b>instance</b></br>
+</td>
+<td></td>
+<td><b>env:</b><br>
+- name: SN_INSTANCE
+</td>
+<td> The ServiceNow instance name, without the domain, service-now.com. If the value is not specified in the task, the value of environment variable C(SN_INSTANCE) will be used instead. </td>
+</tr>
+<tr>
+<td><b>host</b></br>
+</td>
+<td></td>
+<td><b>env:</b><br>
+- name: SN_HOST
+</td>
+<td> The ServiceNow hostname. This value is FQDN for ServiceNow host. If the value is not specified in the task, the value of environment variable C(SN_HOST) will be used instead. Mutually exclusive with C(instance). </td>
+</tr>
+<tr>
+<td><b>filter_results</b></br>
+</td>
+<td><b>Default:</b><br>
+</td>
+<td></td>
+<td> Filter results with sysparm_query encoded query string syntax. Complete list of operators available for filters and queries. </td>
+</tr>
+<tr>
+<td><b>proxy</b></br>
+</td>
+<td><b>Default:</b><br>
+</td>
+<td></td>
+<td> Proxy server to use for requests to ServiceNow. </td>
+</tr>
+<tr>
+<td><b>enhanced</b></br>
+</td>
+<td><b>Default:</b><br>
+False</td>
+<td></td>
+<td> enable enhanced inventory which provides relationship information from CMDB. Requires installation of Update Set. </td>
+</tr>
+<tr>
+<td><b>selection_order</b></br>
+</td>
+<td><b>Default:</b><br>
+ip_address,fqdn,host_name,name</td>
+<td></td>
+<td> Comma seperated string providing ability to define selection preference order. </td>
+</tr>
+<tr>
+<td><b>table</b></br>
+</td>
+<td><b>Default:</b><br>
+cmdb_ci_server</td>
+<td></td>
+<td> The ServiceNow table to query </td>
+</tr>
+<tr>
+<td><b>enhanced_groups</b></br>
+</td>
+<td><b>Default:</b><br>
+True</td>
+<td></td>
+<td> enable enhanced groups from CMDB relationships. Only used if enhanced is enabled. </td>
+</tr>
+<tr>
+<td><b>password</b></br>
+<p style="color:red;font-size:75%">required</p></td>
+<td></td>
+<td><b>env:</b><br>
+- name: SN_PASSWORD
+</td>
+<td> Password for username. If the value is not specified, the value of environment variable C(SN_PASSWORD) will be used instead. </td>
+</tr>
+</table>
+
+## Examples
+```
+
+plugin: servicenow.servicenow.now
+instance: dev89007
+username: admin
+password: password
+keyed_groups:
+ - key: sn_sys_class_name | lower
+ prefix: ''
+ separator: ''
+
+plugin: servicenow.servicenow.now
+host: servicenow.mydomain.com
+username: admin
+password: password
+fields: [name,host_name,fqdn,ip_address,sys_class_name, install_status, classification,vendor]
+keyed_groups:
+ - key: sn_classification | lower
+ prefix: 'env'
+ - key: sn_vendor | lower
+ prefix: ''
+ separator: ''
+ - key: sn_sys_class_name | lower
+ prefix: ''
+ separator: ''
+ - key: sn_install_status | lower
+ prefix: 'status'
+
+plugin: servicenow.servicenow.now
+instance: dev89007
+username: admin
+password: password
+fields:
+ - name
+ - sys_tags
+compose:
+ sn_tags: sn_sys_tags.replace(" ", "").split(',')
+ ansible_host: sn_ip_address
+keyed_groups:
+ - key: sn_tags | lower
+ prefix: 'tag'
+
+``` \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/snow_record.md b/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/snow_record.md
new file mode 100644
index 00000000..a9452daf
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/snow_record.md
@@ -0,0 +1,156 @@
+snow_record - Manage records in ServiceNow
+====================================
+- [Synopsis](Synopsis)
+- [Requirements](Requirements)
+- [Parameters](Parameters)
+- [Examples](Examples)
+
+## Synopsis
+- Creates, deletes and updates a single record in ServiceNow.
+
+## Requirements
+- python pysnow (pysnow)
+
+## Parameters
+
+<table>
+<tr>
+<th> Parameter </th>
+<th> Choices/Defaults </th>
+<th> Configuration </th>
+<th> Comments </th>
+</tr>
+<tr>
+<td><b>number</b></br>
+</td>
+<td></td>
+<td></td>
+<td> Record number to update. Required for C(state:absent). </td>
+</tr>
+<tr>
+<td><b>state</b></br>
+<p style="color:red;font-size:75%">required</p></td>
+<td><b>Choices:</b><br>
+- present
+- absent
+</td>
+<td></td>
+<td> 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. </td>
+</tr>
+<tr>
+<td><b>attachment</b></br>
+</td>
+<td></td>
+<td></td>
+<td> Attach a file to the record. </td>
+</tr>
+<tr>
+<td><b>table</b></br>
+</td>
+<td><b>Default:</b><br>
+incident</td>
+<td></td>
+<td> Table to query for records. </td>
+</tr>
+<tr>
+<td><b>lookup_field</b></br>
+</td>
+<td><b>Default:</b><br>
+number</td>
+<td></td>
+<td> Changes the field that C(number) uses to find records. </td>
+</tr>
+<tr>
+<td><b>data</b></br>
+</td>
+<td></td>
+<td></td>
+<td> key, value pairs of data to load into the record. See Examples. Required for C(state:present). </td>
+</tr>
+</table>
+
+## 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: Grab a user record using OAuth
+ snow_record:
+ username: ansible_test
+ password: my_password
+ client_id: "1234567890abcdef1234567890abcdef"
+ client_secret: "Password1!"
+ 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: Create an incident using host instead of instance
+ snow_record:
+ username: ansible_test
+ password: my_password
+ host: dev99999.mycustom.domain.com
+ state: present
+ data:
+ short_description: "This is a test incident opened by Ansible"
+ priority: 2
+
+- 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
+
+``` \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/snow_record_find.md b/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/snow_record_find.md
new file mode 100644
index 00000000..74eb419a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/snow_record_find.md
@@ -0,0 +1,131 @@
+snow_record_find - Search for multiple records from ServiceNow
+====================================
+- [Synopsis](Synopsis)
+- [Requirements](Requirements)
+- [Parameters](Parameters)
+- [Examples](Examples)
+
+## Synopsis
+- Gets multiple records from a specified table from ServiceNow based on a query dictionary.
+
+## Requirements
+- python pysnow (pysnow)
+
+## Parameters
+
+<table>
+<tr>
+<th> Parameter </th>
+<th> Choices/Defaults </th>
+<th> Configuration </th>
+<th> Comments </th>
+</tr>
+<tr>
+<td><b>table</b></br>
+</td>
+<td><b>Default:</b><br>
+incident</td>
+<td></td>
+<td> Table to query for records. </td>
+</tr>
+<tr>
+<td><b>max_records</b></br>
+</td>
+<td><b>Default:</b><br>
+20</td>
+<td></td>
+<td> Maximum number of records to return. </td>
+</tr>
+<tr>
+<td><b>return_fields</b></br>
+</td>
+<td></td>
+<td></td>
+<td> Fields of the record to return in the json. By default, all fields will be returned. </td>
+</tr>
+<tr>
+<td><b>order_by</b></br>
+</td>
+<td><b>Default:</b><br>
+-created_on</td>
+<td></td>
+<td> Field to sort the results on. Can prefix with "-" or "+" to change descending or ascending sort order. </td>
+</tr>
+<tr>
+<td><b>query</b></br>
+<p style="color:red;font-size:75%">required</p></td>
+<td></td>
+<td></td>
+<td> Dict to query for records. </td>
+</tr>
+</table>
+
+## Examples
+```
+
+- name: Search for incident assigned to group, return specific fields
+ snow_record_find:
+ username: ansible_test
+ password: my_password
+ instance: dev99999
+ table: incident
+ query:
+ assignment_group: d625dccec0a8016700a222a0f7900d06
+ return_fields:
+ - number
+ - opened_at
+
+- name: Search for incident using host instead of instance
+ snow_record_find:
+ username: ansible_test
+ password: my_password
+ host: dev99999.mycustom.domain.com
+ table: incident
+ query:
+ assignment_group: d625dccec0a8016700a222a0f7900d06
+ return_fields:
+ - number
+ - opened_at
+
+- name: Using OAuth, search for incident assigned to group, return specific fields
+ snow_record_find:
+ username: ansible_test
+ password: my_password
+ client_id: "1234567890abcdef1234567890abcdef"
+ client_secret: "Password1!"
+ instance: dev99999
+ table: incident
+ query:
+ assignment_group: d625dccec0a8016700a222a0f7900d06
+ return_fields:
+ - number
+ - opened_at
+
+- name: Find open standard changes with my template
+ snow_record_find:
+ username: ansible_test
+ password: my_password
+ instance: dev99999
+ table: change_request
+ query:
+ AND:
+ equals:
+ active: "True"
+ type: "standard"
+ u_change_stage: "80"
+ contains:
+ u_template: "MY-Template"
+ return_fields:
+ - sys_id
+ - number
+ - sys_created_on
+ - sys_updated_on
+ - u_template
+ - active
+ - type
+ - u_change_stage
+ - sys_created_by
+ - description
+ - short_description
+
+``` \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/templates/docs.md.j2 b/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/templates/docs.md.j2
new file mode 100644
index 00000000..03fd3007
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/docs/templates/docs.md.j2
@@ -0,0 +1,38 @@
+{% if docs.name is defined %}{{ docs.name }}{% else %}{{ docs.module }}{% endif %} - {{ docs.short_description }}
+====================================
+- [Synopsis](Synopsis)
+- [Requirements](Requirements)
+- [Parameters](Parameters)
+- [Examples](Examples)
+
+## Synopsis
+{{ docs.description | to_nice_yaml}}
+## Requirements
+{{ docs.requirements | default('') | to_nice_yaml }}
+## Parameters
+
+<table>
+<tr>
+<th> Parameter </th>
+<th> Choices/Defaults </th>
+<th> Configuration </th>
+<th> Comments </th>
+</tr>
+{% for option in docs.options %}
+<tr>
+<td><b>{{ option }}</b></br>
+{% if docs.options[option]['required'] is defined and docs.options[option]['required'] %}<p style="color:red;font-size:75%">required</p>{% endif %}</td>
+<td>{% if docs.options[option]['choices'] is defined %}<b>Choices:</b><br>
+{{ docs.options[option]['choices'] | to_nice_yaml }}{% endif %}{% if docs.options[option]['default'] is defined %}<b>Default:</b><br>
+{{ docs.options[option]['default'] }}{% endif %}</td>
+<td>{% if docs.options[option]['env'] is defined %}<b>env:</b><br>
+{{ docs.options[option]['env'] | to_nice_yaml }}{% endif %}</td>
+<td>{% if docs.options[option]['description'] is string %} {{docs.options[option]['description']}} {% else %} {% for line in docs.options[option]['description'] %} {{line}} {% endfor %} {% endif %}</td>
+</tr>
+{% endfor %}
+</table>
+
+## Examples
+```
+{{ examples }}
+``` \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/meta/runtime.yml b/collections-debian-merged/ansible_collections/servicenow/servicenow/meta/runtime.yml
new file mode 100644
index 00000000..1f18fd72
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/meta/runtime.yml
@@ -0,0 +1,2 @@
+---
+requires_ansible: '>=2.9.10' \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/doc_fragments/service_now.py b/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/doc_fragments/service_now.py
new file mode 100644
index 00000000..295af3b4
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/doc_fragments/service_now.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Ansible Project
+# 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
+
+
+class ModuleDocFragment(object):
+ # Parameters for Service Now modules
+ DOCUMENTATION = r'''
+options:
+ instance:
+ description:
+ - The ServiceNow instance name, without the domain, service-now.com.
+ - If the value is not specified in the task, the value of environment variable C(SN_INSTANCE) will be used instead.
+ required: false
+ type: str
+ host:
+ description:
+ - The ServiceNow hostname.
+ - This value is FQDN for ServiceNow host.
+ - If the value is not specified in the task, the value of environment variable C(SN_HOST) will be used instead.
+ - Mutually exclusive with C(instance).
+ type: str
+ username:
+ description:
+ - Name of user for connection to ServiceNow.
+ - Required whether using Basic or OAuth authentication.
+ - If the value is not specified in the task, the value of environment variable C(SN_USERNAME) will be used instead.
+ required: false
+ type: str
+ password:
+ description:
+ - Password for username.
+ - Required whether using Basic or OAuth authentication.
+ - If the value is not specified in the task, the value of environment variable C(SN_PASSWORD) will be used instead.
+ required: false
+ type: str
+ client_id:
+ description:
+ - Client ID generated by ServiceNow.
+ required: false
+ type: str
+ client_secret:
+ description:
+ - Client Secret associated with client id.
+ required: false
+ type: str
+'''
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/inventory/now.py b/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/inventory/now.py
new file mode 100644
index 00000000..b3f28975
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/inventory/now.py
@@ -0,0 +1,316 @@
+#
+# Copyright: (c), Ansible Project
+#
+# 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
+
+DOCUMENTATION = r'''
+ name: servicenow.servicenow.now
+ plugin_type: inventory
+ author:
+ - Will Tome (@willtome)
+ - Alex Mittell (@alex_mittell)
+ short_description: ServiceNow Inventory Plugin
+ version_added: "2.10"
+ description:
+ - ServiceNow Inventory plugin.
+ extends_documentation_fragment:
+ - constructed
+ - inventory_cache
+ requirements:
+ - requests
+ options:
+ plugin:
+ description: The name of the ServiceNow Inventory Plugin, this should always be 'servicenow.servicenow.now'.
+ required: True
+ choices: ['servicenow.servicenow.now']
+ instance:
+ description:
+ - The ServiceNow instance name, without the domain, service-now.com.
+ - If the value is not specified in the task, the value of environment variable C(SN_INSTANCE) will be used instead.
+ required: false
+ type: str
+ env:
+ - name: SN_INSTANCE
+ host:
+ description:
+ - The ServiceNow hostname.
+ - This value is FQDN for ServiceNow host.
+ - If the value is not specified in the task, the value of environment variable C(SN_HOST) will be used instead.
+ - Mutually exclusive with C(instance).
+ type: str
+ required: false
+ env:
+ - name: SN_HOST
+ username:
+ description:
+ - Name of user for connection to ServiceNow.
+ - If the value is not specified, the value of environment variable C(SN_USERNAME) will be used instead.
+ required: false
+ type: str
+ env:
+ - name: SN_USERNAME
+ password:
+ description:
+ - Password for username.
+ - If the value is not specified, the value of environment variable C(SN_PASSWORD) will be used instead.
+ required: true
+ type: str
+ env:
+ - name: SN_PASSWORD
+ table:
+ description: The ServiceNow table to query.
+ type: string
+ default: cmdb_ci_server
+ fields:
+ description: Comma seperated string providing additional table columns to add as host vars to each inventory host.
+ type: list
+ default: 'ip_address,fqdn,host_name,sys_class_name,name'
+ selection_order:
+ description: Comma seperated string providing ability to define selection preference order.
+ type: list
+ default: 'ip_address,fqdn,host_name,name'
+ filter_results:
+ description: Filter results with sysparm_query encoded query string syntax. Complete list of operators available for filters and queries.
+ type: string
+ default: ''
+ proxy:
+ description: Proxy server to use for requests to ServiceNow.
+ type: string
+ default: ''
+ enhanced:
+ description:
+ - Enable enhanced inventory which provides relationship information from CMDB.
+ - Requires installation of Update Set located in update_sets directory.
+ type: bool
+ default: False
+ enhanced_groups:
+ description: enable enhanced groups from CMDB relationships. Only used if enhanced is enabled.
+ type: bool
+ default: True
+
+'''
+
+EXAMPLES = r'''
+# Simple Inventory Plugin example
+plugin: servicenow.servicenow.now
+instance: dev89007
+username: admin
+password: password
+keyed_groups:
+ - key: sn_sys_class_name | lower
+ prefix: ''
+ separator: ''
+
+# Using Keyed Groups
+plugin: servicenow.servicenow.now
+host: servicenow.mydomain.com
+username: admin
+password: password
+fields: [name,host_name,fqdn,ip_address,sys_class_name, install_status, classification,vendor]
+keyed_groups:
+ - key: sn_classification | lower
+ prefix: 'env'
+ - key: sn_vendor | lower
+ prefix: ''
+ separator: ''
+ - key: sn_sys_class_name | lower
+ prefix: ''
+ separator: ''
+ - key: sn_install_status | lower
+ prefix: 'status'
+
+# Compose hostvars
+plugin: servicenow.servicenow.now
+instance: dev89007
+username: admin
+password: password
+fields:
+ - name
+ - sys_tags
+compose:
+ sn_tags: sn_sys_tags.replace(" ", "").split(',')
+ ansible_host: sn_ip_address
+keyed_groups:
+ - key: sn_tags | lower
+ prefix: 'tag'
+'''
+
+import netaddr
+try:
+ import requests
+ HAS_REQUESTS = True
+except ImportError:
+ HAS_REQUESTS = False
+
+from ansible.errors import AnsibleError, AnsibleParserError
+from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable, to_safe_group_name
+
+
+class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
+
+ NAME = 'servicenow.servicenow.now'
+
+ def verify_file(self, path):
+ valid = False
+ if super(InventoryModule, self).verify_file(path):
+ if path.endswith(('now.yaml', 'now.yml')):
+ valid = True
+ else:
+ self.display.vvv(
+ 'Skipping due to inventory source not ending in "now.yaml" nor "now.yml"')
+ return valid
+
+ def invoke(self, verb, path, data):
+ auth = requests.auth.HTTPBasicAuth(self.get_option('username'),
+ self.get_option('password'))
+ headers = {
+ "Accept": "application/json",
+ "Content-Type": "application/json",
+ }
+ proxy = self.get_option('proxy')
+
+ if self.get_option('instance'):
+ fqdn = "%s.service-now.com" % (self.get_option('instance'))
+ elif self.get_option('host'):
+ fqdn = self.get_option('host')
+ else:
+ raise AnsibleError("instance or host must be defined")
+
+ # build url
+ self.url = "https://%s/%s" % (fqdn, path)
+ url = self.url
+ self.display.vvv("Connecting to...%s" % url)
+ results = []
+
+ if not self.update_cache:
+ try:
+ results = self._cache[self.cache_key][self.url]
+ except KeyError:
+ pass
+
+ if not results:
+ if self.cache_key not in self._cache:
+ self._cache[self.cache_key] = {self.url: ''}
+
+ session = requests.Session()
+
+ while url:
+ # perform REST operation, accumulating page results
+ response = session.get(url,
+ auth=auth,
+ headers=headers,
+ proxies={
+ 'http': proxy,
+ 'https': proxy
+ })
+ if response.status_code == 400 and self.get_option('enhanced'):
+ raise AnsibleError("http error (%s): %s. Have you installed the enhanced inventory update set on your instance?" %
+ (response.status_code, response.text))
+ elif response.status_code != 200:
+ raise AnsibleError("http error (%s): %s" %
+ (response.status_code, response.text))
+ results += response.json()['result']
+ next_link = response.links.get('next', {})
+ url = next_link.get('url', None)
+
+ self._cache[self.cache_key] = {self.url: results}
+
+ results = {'result': results}
+ return results
+
+ def parse(self, inventory, loader, path,
+ cache=True): # Plugin interface (2)
+ super(InventoryModule, self).parse(inventory, loader, path)
+
+ if not HAS_REQUESTS:
+ raise AnsibleParserError(
+ 'Please install "requests" Python module as this is required'
+ ' for ServiceNow dynamic inventory plugin.')
+
+ self._read_config_data(path)
+ self.cache_key = self.get_cache_key(path)
+
+ self.use_cache = self.get_option('cache') and cache
+ self.update_cache = self.get_option('cache') and not cache
+
+ selection = self.get_option('selection_order')
+ fields = self.get_option('fields')
+ table = self.get_option('table')
+ filter_results = self.get_option('filter_results')
+
+ options = "?sysparm_exclude_reference_link=true&sysparm_display_value=true"
+
+ enhanced = self.get_option('enhanced')
+ enhanced_groups = False
+
+ if enhanced:
+ path = '/api/snc/ansible_inventory' + options + \
+ "&sysparm_fields=" + ','.join(fields) + \
+ "&sysparm_query=" + filter_results + \
+ "&table=" + table
+ enhanced_groups = self.get_option('enhanced_groups')
+ else:
+ path = '/api/now/table/' + table + options + \
+ "&sysparm_fields=" + ','.join(fields) + \
+ "&sysparm_query=" + filter_results
+
+ content = self.invoke('GET', path, None)
+ strict = self.get_option('strict')
+
+ for record in content['result']:
+
+ target = None
+
+ # select name for host
+ for k in selection:
+ if k in record:
+ if record[k] != '':
+ target = record[k]
+ if target is not None:
+ break
+
+ if target is None:
+ continue
+
+ # add host to inventory
+ host_name = self.inventory.add_host(target)
+
+ # set variables for host
+ for k in record.keys():
+ self.inventory.set_variable(host_name, 'sn_%s' % k, record[k])
+
+ # add relationship based groups
+ if enhanced and enhanced_groups:
+ for item in record['child_relationships']:
+ ci = to_safe_group_name(item['ci'])
+ ci_rel_type = to_safe_group_name(
+ item['ci_rel_type'].split('__')[0])
+ ci_type = to_safe_group_name(item['ci_type'])
+ if ci != '' and ci_rel_type != '' and ci_type != '':
+ child_group = "%s_%s" % (ci, ci_rel_type)
+ self.inventory.add_group(child_group)
+ self.inventory.add_child(child_group, host_name)
+
+ for item in record['parent_relationships']:
+ ci = to_safe_group_name(item['ci'])
+ ci_rel_type = to_safe_group_name(
+ item['ci_rel_type'].split('__')[-1])
+ ci_type = to_safe_group_name(item['ci_type'])
+
+ if ci != '' and ci_rel_type != '' and ci_type != '':
+ child_group = "%s_%s" % (ci, ci_rel_type)
+ self.inventory.add_group(child_group)
+ self.inventory.add_child(child_group, host_name)
+
+ self._set_composite_vars(
+ self.get_option('compose'),
+ self.inventory.get_host(host_name).get_vars(), host_name,
+ strict)
+
+ self._add_host_to_composed_groups(self.get_option('groups'),
+ dict(), host_name, strict)
+ self._add_host_to_keyed_groups(self.get_option('keyed_groups'),
+ dict(), host_name, strict)
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/module_utils/service_now.py b/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/module_utils/service_now.py
new file mode 100644
index 00000000..a3caa867
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/module_utils/service_now.py
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Ansible Project
+# Copyright: (c) 2017, Tim Rightnour <thegarbledone@gmail.com>
+# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+import traceback
+from ansible.module_utils.basic import env_fallback, missing_required_lib
+
+# Pull in pysnow
+HAS_PYSNOW = False
+PYSNOW_IMP_ERR = None
+try:
+ import pysnow
+ HAS_PYSNOW = True
+except ImportError:
+ PYSNOW_IMP_ERR = traceback.format_exc()
+
+
+class ServiceNowClient(object):
+ def __init__(self, module):
+ """
+ Constructor
+ """
+ if not HAS_PYSNOW:
+ module.fail_json(msg=missing_required_lib('pysnow'), exception=PYSNOW_IMP_ERR)
+
+ self.module = module
+ self.params = module.params
+ self.client_id = self.params['client_id']
+ self.client_secret = self.params['client_secret']
+ self.username = self.params['username']
+ self.password = self.params['password']
+ self.instance = self.params['instance']
+ self.host = self.params['host']
+ self.session = {'token': None}
+ self.conn = None
+
+ def login(self):
+ result = dict(
+ changed=False
+ )
+
+ if self.params['client_id'] is not None:
+ try:
+ self.conn = pysnow.OAuthClient(client_id=self.client_id,
+ client_secret=self.client_secret,
+ token_updater=self.updater,
+ instance=self.instance,
+ host=self.host)
+ except Exception as detail:
+ self.module.fail_json(msg='Could not connect to ServiceNow: {0}'.format(str(detail)), **result)
+ if not self.session['token']:
+ # No previous token exists, Generate new.
+ try:
+ self.session['token'] = self.conn.generate_token(self.username, self.password)
+ except pysnow.exceptions.TokenCreateError as detail:
+ self.module.fail_json(msg='Unable to generate a new token: {0}'.format(str(detail)), **result)
+
+ self.conn.set_token(self.session['token'])
+ elif self.username is not None:
+ try:
+ self.conn = pysnow.Client(instance=self.instance,
+ host=self.host,
+ user=self.username,
+ password=self.password)
+ except Exception as detail:
+ self.module.fail_json(msg='Could not connect to ServiceNow: {0}'.format(str(detail)), **result)
+ else:
+ snow_error = "Must specify username/password. Also client_id/client_secret if using OAuth."
+ self.module.fail_json(msg=snow_error, **result)
+
+ def updater(self, new_token):
+ self.session['token'] = new_token
+ self.conn = pysnow.OAuthClient(client_id=self.client_id,
+ client_secret=self.client_secret,
+ token_updater=self.updater,
+ instance=self.instance,
+ host=self.host)
+ try:
+ self.conn.set_token(self.session['token'])
+ except pysnow.exceptions.MissingToken:
+ snow_error = "Token is missing"
+ self.module.fail_json(msg=snow_error)
+ except Exception as detail:
+ self.module.fail_json(msg='Could not refresh token: {0}'.format(str(detail)))
+
+ @staticmethod
+ def snow_argument_spec():
+ return dict(
+ instance=dict(type='str', required=False, fallback=(env_fallback, ['SN_INSTANCE'])),
+ username=dict(type='str', required=False, fallback=(env_fallback, ['SN_USERNAME'])),
+ host=dict(type='str', required=False, fallback=(env_fallback, ['SN_HOST'])),
+ password=dict(type='str', required=False, no_log=True, fallback=(env_fallback, ['SN_PASSWORD'])),
+ client_id=dict(type='str', no_log=True),
+ client_secret=dict(type='str', no_log=True),
+ )
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/modules/snow_record.py b/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/modules/snow_record.py
new file mode 100644
index 00000000..6d4f7ce2
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/modules/snow_record.py
@@ -0,0 +1,387 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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
+
+
+DOCUMENTATION = r'''
+---
+module: snow_record
+short_description: Manage records in ServiceNow
+description:
+ - Creates, deletes and updates a single record in ServiceNow.
+options:
+ table:
+ description:
+ - Table to query for records.
+ required: false
+ default: incident
+ type: str
+ 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
+ type: str
+ data:
+ description:
+ - key, value pairs of data to load into the record. See Examples.
+ - Required for C(state:present).
+ type: dict
+ number:
+ description:
+ - Record number to update.
+ - Required for C(state:absent).
+ required: false
+ type: str
+ lookup_field:
+ description:
+ - Changes the field that C(number) uses to find records.
+ required: false
+ default: number
+ type: str
+ attachment:
+ description:
+ - Attach a file to the record.
+ required: false
+ type: str
+ display_value:
+ description:
+ - sysparm_display_value
+ type: bool
+ required: false
+ default: false
+ exclude_reference_link:
+ description:
+ - sysparm_exclude_reference_link
+ type: bool
+ required: false
+ default: false
+ suppress_pagination_header:
+ description:
+ - sysparm_suppress_pagination_header
+ type: bool
+ required: false
+ default: false
+requirements:
+ - python pysnow (pysnow)
+author:
+ - Tim Rightnour (@garbled1)
+extends_documentation_fragment:
+- servicenow.servicenow.service_now.documentation
+
+'''
+
+EXAMPLES = r'''
+- name: Grab a user record
+ servicenow.servicenow.snow_record:
+ username: ansible_test
+ password: my_password
+ instance: dev99999
+ state: present
+ number: 62826bf03710200044e0bfc8bcbe5df1
+ table: sys_user
+ lookup_field: sys_id
+
+- name: Grab a user record using OAuth
+ servicenow.servicenow.snow_record:
+ username: ansible_test
+ password: my_password
+ client_id: "1234567890abcdef1234567890abcdef"
+ client_secret: "Password1!"
+ instance: dev99999
+ state: present
+ number: 62826bf03710200044e0bfc8bcbe5df1
+ table: sys_user
+ lookup_field: sys_id
+
+- name: Create an incident
+ servicenow.servicenow.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: Create an incident using host instead of instance
+ servicenow.servicenow.snow_record:
+ username: ansible_test
+ password: my_password
+ host: dev99999.mycustom.domain.com
+ state: present
+ data:
+ short_description: "This is a test incident opened by Ansible"
+ priority: 2
+
+- name: Delete the record we just made
+ servicenow.servicenow.snow_record:
+ username: admin
+ password: xxxxxxx
+ instance: dev99999
+ state: absent
+ number: "{{new_incident['record']['number']}}"
+
+- name: Delete a non-existant record
+ servicenow.servicenow.snow_record:
+ username: ansible_test
+ password: my_password
+ instance: dev99999
+ state: absent
+ number: 9872354
+ failed_when: false
+
+- name: Update an incident
+ servicenow.servicenow.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
+ servicenow.servicenow.snow_record:
+ username: ansible_test
+ password: my_password
+ instance: dev99999
+ state: present
+ number: INC0000055
+ attachment: README.md
+ tags: attach
+'''
+
+RETURN = r'''
+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
+from ansible_collections.servicenow.servicenow.plugins.module_utils.service_now import ServiceNowClient
+
+try:
+ # This is being handled by ServiceNowClient
+ import pysnow
+except ImportError:
+ pass
+
+
+def run_module():
+ # define the available arguments/parameters that a user can pass to
+ # the module
+ module_args = ServiceNowClient.snow_argument_spec()
+ module_args.update(
+ 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'),
+ display_value=dict(default=False, type='bool', required=False),
+ exclude_reference_link=dict(default=False, type='bool', required=False),
+ suppress_pagination_header=dict(default=False, type='bool', required=False)
+ )
+ module_required_together = [
+ ['client_id', 'client_secret']
+ ]
+ module_required_if = [
+ ['state', 'absent', ['number']],
+ ]
+
+ module_mutually_exclusive = [
+ ['host', 'instance'],
+ ]
+
+ module_required_one_of = [
+ ['host', 'instance'],
+ ]
+
+ module = AnsibleModule(
+ argument_spec=module_args,
+ supports_check_mode=True,
+ required_together=module_required_together,
+ required_if=module_required_if,
+ required_one_of=module_required_one_of,
+ mutually_exclusive=module_mutually_exclusive,
+ )
+
+ # Connect to ServiceNow
+ service_now_client = ServiceNowClient(module)
+ service_now_client.login()
+ conn = service_now_client.conn
+
+ params = module.params
+ instance = params['instance']
+ host = params['host']
+ table = params['table']
+ state = params['state']
+ number = params['number']
+ data = params['data']
+ lookup_field = params['lookup_field']
+ display_value = params['display_value']
+ exclude_reference_link = params['exclude_reference_link']
+ suppress_pagination_header = params['suppress_pagination_header']
+
+ result = dict(
+ changed=False,
+ instance=instance,
+ host=host,
+ table=table,
+ number=number,
+ lookup_field=lookup_field,
+ display_value=display_value,
+ exclude_reference_link=exclude_reference_link,
+ suppress_pagination_header=suppress_pagination_header
+ )
+
+ # 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
+
+ conn.parameters.display_value = display_value
+ conn.parameters.exclude_reference_link = exclude_reference_link
+ conn.parameters.suppress_pagination_header = suppress_pagination_header
+
+ # 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:
+ resource = conn.resource(api_path='/table/' + table)
+ response = resource.get(query={lookup_field: number})
+ res = response.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(to_native(detail)), **result)
+
+ # Let's simulate modification
+ else:
+ try:
+ resource = conn.resource(api_path='/table/' + table)
+ response = resource.get(query={lookup_field: number})
+ res = response.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(to_native(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:
+ resource = conn.resource(api_path='/table/' + table)
+ response = resource.create(payload=dict(data))
+ record = response.one()
+ except pysnow.exceptions.UnexpectedResponseFormat 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)
+ except pysnow.legacy_exceptions.UnexpectedResponse as e:
+ module.fail_json(msg="Failed to create record due to %s" % to_native(e), **result)
+ result['record'] = record
+ result['changed'] = True
+
+ # we are deleting a record
+ elif state == 'absent':
+ try:
+ resource = conn.resource(api_path='/table/' + table)
+ res = resource.delete(query={lookup_field: number})
+ 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.exceptions.UnexpectedResponseFormat 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 pysnow.legacy_exceptions.UnexpectedResponse as e:
+ module.fail_json(msg="Failed to delete record due to %s" % to_native(e), **result)
+ except Exception as detail:
+ snow_error = "Failed to delete record: {0}".format(to_native(detail))
+ module.fail_json(msg=snow_error, **result)
+ result['record'] = res
+ result['changed'] = True
+
+ # We want to update a record
+ else:
+ try:
+ resource = conn.resource(api_path='/table/' + table)
+ response = resource.get(query={lookup_field: number})
+ record = response.one()
+ if data is not None:
+ res = response.update(data)
+ result['record'] = record
+ result['changed'] = True
+ else:
+ result['record'] = record
+ 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.exceptions.UnexpectedResponseFormat 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 pysnow.legacy_exceptions.UnexpectedResponse as e:
+ module.fail_json(msg="Failed to update record due to %s" % to_native(e), **result)
+ except Exception as detail:
+ snow_error = "Failed to update record: {0}".format(to_native(detail))
+ module.fail_json(msg=snow_error, **result)
+
+ module.exit_json(**result)
+
+
+def main():
+ run_module()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/modules/snow_record_find.py b/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/modules/snow_record_find.py
new file mode 100644
index 00000000..b6e79b65
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/plugins/modules/snow_record_find.py
@@ -0,0 +1,318 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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
+
+DOCUMENTATION = r'''
+---
+module: snow_record_find
+short_description: Search for multiple records from ServiceNow
+description:
+ - Gets multiple records from a specified table from ServiceNow based on a query dictionary.
+options:
+ table:
+ description:
+ - Table to query for records.
+ type: str
+ required: false
+ default: incident
+ query:
+ description:
+ - Dict to query for records.
+ type: dict
+ required: true
+ max_records:
+ description:
+ - Maximum number of records to return.
+ type: int
+ required: false
+ default: 20
+ display_value:
+ description:
+ - sysparm_display_value
+ type: bool
+ required: false
+ default: false
+ exclude_reference_link:
+ description:
+ - sysparm_exclude_reference_link
+ type: bool
+ required: false
+ default: false
+ suppress_pagination_header:
+ description:
+ - sysparm_suppress_pagination_header
+ type: bool
+ required: false
+ default: false
+ order_by:
+ description:
+ - Field to sort the results on.
+ - Can prefix with "-" or "+" to change descending or ascending sort order.
+ type: str
+ default: "-created_on"
+ required: false
+ return_fields:
+ description:
+ - Fields of the record to return in the json.
+ - By default, all fields will be returned.
+ type: list
+ required: false
+ elements: str
+requirements:
+ - python pysnow (pysnow)
+author:
+ - Tim Rightnour (@garbled1)
+extends_documentation_fragment:
+- servicenow.servicenow.service_now.documentation
+
+'''
+
+EXAMPLES = r'''
+- name: Search for incident assigned to group, return specific fields
+ servicenow.servicenow.snow_record_find:
+ username: ansible_test
+ password: my_password
+ instance: dev99999
+ table: incident
+ query:
+ assignment_group: d625dccec0a8016700a222a0f7900d06
+ return_fields:
+ - number
+ - opened_at
+
+- name: Search for incident using host instead of instance
+ servicenow.servicenow.snow_record_find:
+ username: ansible_test
+ password: my_password
+ host: dev99999.mycustom.domain.com
+ table: incident
+ query:
+ assignment_group: d625dccec0a8016700a222a0f7900d06
+ return_fields:
+ - number
+ - opened_at
+
+- name: Using OAuth, search for incident assigned to group, return specific fields
+ servicenow.servicenow.snow_record_find:
+ username: ansible_test
+ password: my_password
+ client_id: "1234567890abcdef1234567890abcdef"
+ client_secret: "Password1!"
+ instance: dev99999
+ table: incident
+ query:
+ assignment_group: d625dccec0a8016700a222a0f7900d06
+ return_fields:
+ - number
+ - opened_at
+
+- name: Find open standard changes with my template
+ servicenow.servicenow.snow_record_find:
+ username: ansible_test
+ password: my_password
+ instance: dev99999
+ table: change_request
+ query:
+ AND:
+ equals:
+ active: "True"
+ type: "standard"
+ u_change_stage: "80"
+ contains:
+ u_template: "MY-Template"
+ return_fields:
+ - sys_id
+ - number
+ - sys_created_on
+ - sys_updated_on
+ - u_template
+ - active
+ - type
+ - u_change_stage
+ - sys_created_by
+ - description
+ - short_description
+'''
+
+RETURN = r'''
+record:
+ description: The full contents of the matching ServiceNow records as a list of records.
+ type: dict
+ returned: always
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.servicenow.servicenow.plugins.module_utils.service_now import ServiceNowClient
+from ansible.module_utils._text import to_native
+
+try:
+ # This is being managed by ServiceNowClient
+ import pysnow
+except ImportError:
+ pass
+
+
+class BuildQuery(object):
+ '''
+ This is a BuildQuery manipulation class that constructs
+ a pysnow.QueryBuilder object based on data input.
+ '''
+
+ def __init__(self, module):
+ self.module = module
+ self.logic_operators = ["AND", "OR", "NQ"]
+ self.condition_operator = {
+ 'equals': self._condition_closure,
+ 'not_equals': self._condition_closure,
+ 'contains': self._condition_closure,
+ 'not_contains': self._condition_closure,
+ 'starts_with': self._condition_closure,
+ 'ends_with': self._condition_closure,
+ 'greater_than': self._condition_closure,
+ 'less_than': self._condition_closure,
+ }
+ self.accepted_cond_ops = self.condition_operator.keys()
+ self.append_operator = False
+ self.simple_query = True
+ self.data = module.params['query']
+
+ def _condition_closure(self, cond, query_field, query_value):
+ self.qb.field(query_field)
+ getattr(self.qb, cond)(query_value)
+
+ def _iterate_fields(self, data, logic_op, cond_op):
+ if isinstance(data, dict):
+ for query_field, query_value in data.items():
+ if self.append_operator:
+ getattr(self.qb, logic_op)()
+ self.condition_operator[cond_op](cond_op, query_field, query_value)
+ self.append_operator = True
+ else:
+ self.module.fail_json(msg='Query is not in a supported format')
+
+ def _iterate_conditions(self, data, logic_op):
+ if isinstance(data, dict):
+ for cond_op, fields in data.items():
+ if (cond_op in self.accepted_cond_ops):
+ self._iterate_fields(fields, logic_op, cond_op)
+ else:
+ self.module.fail_json(msg='Supported conditions: {0}'.format(str(self.condition_operator.keys())))
+ else:
+ self.module.fail_json(msg='Supported conditions: {0}'.format(str(self.condition_operator.keys())))
+
+ def _iterate_operators(self, data):
+ if isinstance(data, dict):
+ for logic_op, cond_op in data.items():
+ if (logic_op in self.logic_operators):
+ self.simple_query = False
+ self._iterate_conditions(cond_op, logic_op)
+ elif self.simple_query:
+ self.condition_operator['equals']('equals', logic_op, cond_op)
+ break
+ else:
+ self.module.fail_json(msg='Query is not in a supported format')
+ else:
+ self.module.fail_json(msg='Supported operators: {0}'.format(str(self.logic_operators)))
+
+ def build_query(self):
+ self.qb = pysnow.QueryBuilder()
+ self._iterate_operators(self.data)
+ return (self.qb)
+
+
+def run_module():
+ # define the available arguments/parameters that a user can pass to
+ # the module
+ module_args = ServiceNowClient.snow_argument_spec()
+ module_args.update(
+ table=dict(type='str', required=False, default='incident'),
+ query=dict(type='dict', required=True),
+ max_records=dict(default=20, type='int', required=False),
+ display_value=dict(default=False, type='bool', required=False),
+ exclude_reference_link=dict(default=False, type='bool', required=False),
+ suppress_pagination_header=dict(default=False, type='bool', required=False),
+ order_by=dict(default='-created_on', type='str', required=False),
+ return_fields=dict(default=[], type='list', required=False, elements='str')
+ )
+ module_required_together = [
+ ['client_id', 'client_secret']
+ ]
+
+ module_mutually_exclusive = [
+ ['host', 'instance'],
+ ]
+
+ module_required_one_of = [
+ ['host', 'instance'],
+ ]
+
+ module = AnsibleModule(
+ argument_spec=module_args,
+ supports_check_mode=True,
+ required_together=module_required_together,
+ required_one_of=module_required_one_of,
+ mutually_exclusive=module_mutually_exclusive,
+ )
+
+ # Connect to ServiceNow
+ service_now_client = ServiceNowClient(module)
+ service_now_client.login()
+ conn = service_now_client.conn
+
+ params = module.params
+ instance = params['instance']
+ host = params['host']
+ table = params['table']
+ query = params['query']
+ max_records = params['max_records']
+ display_value = params['display_value']
+ exclude_reference_link = params['exclude_reference_link']
+ suppress_pagination_header = params['suppress_pagination_header']
+ return_fields = params['return_fields']
+
+ result = dict(
+ changed=False,
+ instance=instance,
+ host=host,
+ table=table,
+ query=query,
+ max_records=max_records,
+ display_value=display_value,
+ exclude_reference_link=exclude_reference_link,
+ suppress_pagination_header=suppress_pagination_header,
+ return_fields=return_fields
+ )
+
+ # Do the lookup
+ try:
+ bq = BuildQuery(module)
+ qb = bq.build_query()
+ table = conn.resource(api_path='/table/' + table)
+
+ table.parameters.display_value = display_value
+ table.parameters.exclude_reference_link = exclude_reference_link
+ table.parameters.suppress_pagination_header = suppress_pagination_header
+
+ response = table.get(
+ query=qb,
+ limit=max_records,
+ fields=return_fields)
+ except Exception as detail:
+ module.fail_json(msg='Failed to find record: {0}'.format(to_native(detail)), **result)
+
+ result['record'] = response.all()
+
+ module.exit_json(**result)
+
+
+def main():
+ run_module()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/requirements.txt b/collections-debian-merged/ansible_collections/servicenow/servicenow/requirements.txt
new file mode 100644
index 00000000..45188e65
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/requirements.txt
@@ -0,0 +1,2 @@
+pysnow
+netaddr
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/enhanced.now.yml b/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/enhanced.now.yml
new file mode 100644
index 00000000..bc0f1787
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/enhanced.now.yml
@@ -0,0 +1,10 @@
+---
+plugin: servicenow.servicenow.now
+instance: dev93775.service-now.com
+username: admin
+password: knTVFcRlD6d9
+selection_order: name
+enhanced: True
+#keyed_groups:
+# - key: sn_sys_class_name
+# prefix: sn
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/module_test.yml b/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/module_test.yml
new file mode 100644
index 00000000..8a8b85b7
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/module_test.yml
@@ -0,0 +1,36 @@
+---
+- hosts: localhost
+ gather_facts: no
+ vars:
+ sn_instance: dev89007
+ login: &login
+ username: admin
+ password: ha53wiaYCKDX
+
+ tasks:
+ - name: test with instance
+ servicenow.servicenow.snow_record:
+ state: present
+ table: change_request
+ instance: "{{ sn_instance }}"
+ data:
+ short_description: "Test 1 from Ansible Collection"
+ <<: *login
+
+ - name: test with instance
+ servicenow.servicenow.snow_record:
+ state: present
+ table: change_request
+ host: "{{ sn_instance }}.service-now.com"
+ data:
+ short_description: "Test 2 from Ansible Collection"
+ <<: *login
+
+ - name: find test records
+ servicenow.servicenow.snow_record_find:
+ table: change_request
+ instance: "{{ sn_instance }}"
+ query:
+ starts_with:
+ - short_description: "Test"
+ <<: *login \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/module_test_cmdb_ci_server.yml b/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/module_test_cmdb_ci_server.yml
new file mode 100644
index 00000000..fbe3a1bd
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/module_test_cmdb_ci_server.yml
@@ -0,0 +1,220 @@
+---
+- hosts: localhost
+ gather_facts: no
+ vars:
+ sn_instance: dev89007
+ login: &login
+ username: admin
+ password: ha53wiaYCKDX
+
+ tasks:
+ - set_fact:
+ name_prefix: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=8') }}"
+
+ # create
+ - name: test create record
+ servicenow.servicenow.snow_record:
+ state: present
+ table: cmdb_ci_server
+ instance: "{{ sn_instance }}"
+ display_value: True
+ data:
+ name: test-{{ name_prefix }}-00{{ item }}
+ <<: *login
+ register: result
+ loop: [11, 12, 21, 22]
+
+ - assert:
+ that:
+ - result.results is defined
+ - result.results|length == 4
+ - result.results[0].record is defined
+ - result.results[0].record.name is defined
+ - result.results[0].record.name == "test-{{ name_prefix }}-0011"
+ - result.results[0].record.sys_domain is defined
+ - result.results[0].record.sys_domain.display_value is defined
+ - result.results[0].record.sys_domain.display_value == "global"
+
+ # update
+ - name: test update one record
+ servicenow.servicenow.snow_record:
+ host: "{{ sn_instance }}.service-now.com"
+ table: cmdb_ci_server
+ lookup_field: name
+ number: "test-{{ name_prefix }}-0022"
+ data:
+ short_description: comment1
+ state: present
+ <<: *login
+ register: result
+
+ - assert:
+ that:
+ - result.changed
+
+ - name: test update, find updated record
+ servicenow.servicenow.snow_record_find:
+ host: "{{ sn_instance }}.service-now.com"
+ table: cmdb_ci_server
+ query:
+ name: "test-{{ name_prefix }}-0022"
+ <<: *login
+ register: result
+
+ - assert:
+ that:
+ - result.record is defined
+ - result.record|length == 1
+ - result.record[0].name is defined
+ - result.record[0].name == "test-{{ name_prefix }}-0022"
+ - result.record[0].short_description is defined
+ - result.record[0].short_description == "comment1"
+
+ # search
+ - name: test find one record
+ servicenow.servicenow.snow_record_find:
+ host: "{{ sn_instance }}.service-now.com"
+ table: cmdb_ci_server
+ query:
+ name: test-{{ name_prefix }}-0022
+ <<: *login
+ register: result
+
+ - assert:
+ that:
+ - result.record|length == 1
+ - result.record[0].name is defined
+ - result.record[0].name == "test-{{ name_prefix }}-0022"
+
+ - name: test find one record, return_fields
+ servicenow.servicenow.snow_record_find:
+ host: "{{ sn_instance }}.service-now.com"
+ table: cmdb_ci_server
+ return_fields:
+ - name
+ - short_description
+ query:
+ name: test-{{ name_prefix }}-0011
+ <<: *login
+ register: result
+
+ - assert:
+ that:
+ - result.record|length == 1
+ - result.record[0]|length == 2
+ - result.record[0].name is defined
+ - result.record[0].short_description is defined
+
+ - name: test find one out of many record
+ servicenow.servicenow.snow_record_find:
+ host: "{{ sn_instance }}.service-now.com"
+ table: cmdb_ci_server
+ query:
+ name: test-{{ name_prefix }}-0011
+ <<: *login
+ register: result
+
+ - assert:
+ that:
+ - result.record|length == 1
+ - result.record[0].name == "test-{{ name_prefix }}-0011"
+ - result.record[0].model_id is defined
+ - result.record[0].model_id.link is defined
+
+ - name: test find one out of many record with display_value=True
+ servicenow.servicenow.snow_record_find:
+ host: "{{ sn_instance }}.service-now.com"
+ table: cmdb_ci_server
+ display_value: True
+ query:
+ name: test-{{ name_prefix }}-0011
+ <<: *login
+ register: result
+
+ - assert:
+ that:
+ - result.record|length == 1
+ - result.display_value
+ - not result.exclude_reference_link
+ - result.record[0].name == "test-{{ name_prefix }}-0011"
+ - result.record[0].sys_domain is defined
+ - result.record[0].sys_domain.display_value is defined
+ - result.record[0].sys_domain.display_value == "global"
+
+ - name: test find one out of many record with display_value=True exclude_reference_link=True
+ servicenow.servicenow.snow_record_find:
+ host: "{{ sn_instance }}.service-now.com"
+ table: cmdb_ci_server
+ display_value: True
+ exclude_reference_link: True
+ query:
+ name: test-{{ name_prefix }}-0011
+ <<: *login
+ register: result
+
+ - assert:
+ that:
+ - result.display_value
+ - result.exclude_reference_link
+ - result.record|length == 1
+ - result.record[0].name == "test-{{ name_prefix }}-0011"
+ - result.record[0].model_id is defined
+ - result.record[0].model_id == "Unknown"
+
+ - name: test find only 2 records out of many
+ servicenow.servicenow.snow_record_find:
+ host: "{{ sn_instance }}.service-now.com"
+ table: cmdb_ci_server
+ query:
+ AND:
+ contains:
+ name: "test-{{ name_prefix }}-001"
+ <<: *login
+ register: result
+
+ - assert:
+ that:
+ - result.record|length == 2
+
+ - name: test find many, want only 3
+ servicenow.servicenow.snow_record_find:
+ host: "{{ sn_instance }}.service-now.com"
+ table: cmdb_ci_server
+ max_records: 3
+ query:
+ AND:
+ contains:
+ name: "test-{{ name_prefix }}"
+ <<: *login
+ register: result
+
+ - assert:
+ that:
+ - result.record|length == 3
+
+ # remove
+ - name: remove record
+ servicenow.servicenow.snow_record:
+ state: absent
+ table: cmdb_ci_server
+ instance: "{{ sn_instance }}"
+ number: "test-{{ name_prefix }}-00{{ item }}"
+ lookup_field: name
+ <<: *login
+ loop: [11, 12, 21, 22]
+
+ # search result is empty
+ - name: test find no record
+ servicenow.servicenow.snow_record_find:
+ host: "{{ sn_instance }}.service-now.com"
+ table: cmdb_ci_server
+ query:
+ AND:
+ contains:
+ name: "test-{{ name_prefix }}"
+ <<: *login
+ register: result
+
+ - assert:
+ that:
+ - result.record|length == 0
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/network.enhanced.now.yml b/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/network.enhanced.now.yml
new file mode 100644
index 00000000..ebe1d395
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/network.enhanced.now.yml
@@ -0,0 +1,8 @@
+---
+plugin: servicenow.servicenow.now
+instance: dev93775.service-now.com
+username: admin
+password: le4MnTLd3bCK
+table: cmdb_ci_netgear
+selection_order: name
+enhanced: True
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/now.yml b/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/now.yml
new file mode 100644
index 00000000..449c58f0
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/tests/now.yml
@@ -0,0 +1,26 @@
+---
+plugin: servicenow.servicenow.now
+host: dev95176.service-now.com
+username: admin
+password: P0aX7VAtnyXm
+selection_order: name
+fields:
+ - os
+ - ip_address
+ - fqdn
+ - host_name
+ - sys_class_name
+ - name
+ - disk_space
+ - cpu_count
+groups:
+ large: (sn_disk_space | int) > 100
+ SAP: inventory_hostname.startswith('SAP')
+keyed_groups:
+ - key: sn_sys_class_name
+ prefix: sn
+ - key: os_class
+ prefix: ''
+ separator: ''
+compose:
+ os_class: sn_os.split(' ')[0] \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/update_sets/README.md b/collections-debian-merged/ansible_collections/servicenow/servicenow/update_sets/README.md
new file mode 100644
index 00000000..d3990837
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/update_sets/README.md
@@ -0,0 +1,5 @@
+# Update Sets for Ansible Integration
+This directory provides update sets that may be required to unlock functionality in ServiceNow.
+
+## ansible_enhanced_inventory
+This update set installs a scripted REST API into your ServiceNow instance. This is required for the `enhanced` parameter in the `now` inventory plugin to function. "enhanced" provides CI relationship data to the plugin so that it can build additional groups in your inventory. \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/servicenow/servicenow/update_sets/ansible_enhanced_inventory.xml b/collections-debian-merged/ansible_collections/servicenow/servicenow/update_sets/ansible_enhanced_inventory.xml
new file mode 100644
index 00000000..ddcf7976
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/servicenow/servicenow/update_sets/ansible_enhanced_inventory.xml
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="UTF-8"?><unload unload_date="2020-01-30 23:28:32">
+<sys_remote_update_set action="INSERT_OR_UPDATE">
+<application display_value="Global">global</application>
+<application_name>Global</application_name>
+<application_scope>global</application_scope>
+<application_version/>
+<collisions/>
+<commit_date/>
+<deleted/>
+<description/>
+<inserted/>
+<name>Ansible_Inventory</name>
+<origin_sys_id/>
+<parent display_value=""/>
+<release_date/>
+<remote_base_update_set display_value=""/>
+<remote_parent_id/>
+<remote_sys_id>d9552962db66481085449eb5db961931</remote_sys_id>
+<state>loaded</state>
+<summary/>
+<sys_class_name>sys_remote_update_set</sys_class_name>
+<sys_created_by>admin</sys_created_by>
+<sys_created_on>2020-01-30 23:28:31</sys_created_on>
+<sys_id>674a39afdb220010081a3ec8f496197d</sys_id>
+<sys_mod_count>0</sys_mod_count>
+<sys_updated_by>admin</sys_updated_by>
+<sys_updated_on>2020-01-30 23:28:31</sys_updated_on>
+<update_set display_value=""/>
+<update_source display_value=""/>
+<updated/>
+</sys_remote_update_set>
+<sys_update_xml action="INSERT_OR_UPDATE">
+<action>INSERT_OR_UPDATE</action>
+<application display_value="Global">global</application>
+<category>customer</category>
+<comments/>
+<name>sys_ws_query_parameter_map_9e0a692adb66481085449eb5db961931</name>
+<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_ws_query_parameter_map"><sys_ws_query_parameter_map action="INSERT_OR_UPDATE"><sys_class_name>sys_ws_query_parameter_map</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2020-01-27 19:44:45</sys_created_on><sys_customer_update>false</sys_customer_update><sys_id>9e0a692adb66481085449eb5db961931</sys_id><sys_mod_count>0</sys_mod_count><sys_name>3f2a692adb66481085449eb5db9619e2</sys_name><sys_package display_value="Global" source="global">global</sys_package><sys_policy/><sys_replace_on_upgrade>false</sys_replace_on_upgrade><sys_scope display_value="Global">global</sys_scope><sys_update_name>sys_ws_query_parameter_map_9e0a692adb66481085449eb5db961931</sys_update_name><sys_updated_by>admin</sys_updated_by><sys_updated_on>2020-01-27 19:44:45</sys_updated_on><web_service_operation display_value="Ansible Inventory">20b521a2db66481085449eb5db96190f</web_service_operation><web_service_query_parameter display_value="sysparm_fields">3f2a692adb66481085449eb5db9619e2</web_service_query_parameter></sys_ws_query_parameter_map></record_update>]]></payload>
+<payload_hash>1820109461</payload_hash>
+<remote_update_set display_value="Ansible_Inventory">674a39afdb220010081a3ec8f496197d</remote_update_set>
+<replace_on_upgrade>false</replace_on_upgrade>
+<sys_created_by>admin</sys_created_by>
+<sys_created_on>2020-01-30 23:28:31</sys_created_on>
+<sys_id>2b4a39afdb220010081a3ec8f496197e</sys_id>
+<sys_mod_count>0</sys_mod_count>
+<sys_recorded_at>16fe888ecab0000001</sys_recorded_at>
+<sys_updated_by>admin</sys_updated_by>
+<sys_updated_on>2020-01-30 23:28:31</sys_updated_on>
+<table/>
+<target_name>3f2a692adb66481085449eb5db9619e2</target_name>
+<type>Scripted REST Query Parameter Associatio</type>
+<update_domain>global</update_domain>
+<update_guid>645a2d2a0d6648100f79ab3c3f9ebb43</update_guid>
+<update_guid_history>645a2d2a0d6648100f79ab3c3f9ebb43:1820109461</update_guid_history>
+<update_set display_value=""/>
+<view/>
+</sys_update_xml>
+<sys_update_xml action="INSERT_OR_UPDATE">
+<action>INSERT_OR_UPDATE</action>
+<application display_value="Global">global</application>
+<category>customer</category>
+<comments/>
+<name>sys_ws_query_parameter_3f2a692adb66481085449eb5db9619e2</name>
+<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_ws_query_parameter"><sys_ws_query_parameter action="INSERT_OR_UPDATE"><example_value>fqdn,host_name,ip_address,name,sys_class_name</example_value><name>sysparm_fields</name><required>true</required><short_description>field paramters for searching cmdb_ci_server</short_description><sys_class_name>sys_ws_query_parameter</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2020-01-27 19:44:42</sys_created_on><sys_customer_update>false</sys_customer_update><sys_id>3f2a692adb66481085449eb5db9619e2</sys_id><sys_mod_count>1</sys_mod_count><sys_name>sysparm_fields</sys_name><sys_package display_value="Global" source="global">global</sys_package><sys_policy/><sys_replace_on_upgrade>false</sys_replace_on_upgrade><sys_scope display_value="Global">global</sys_scope><sys_update_name>sys_ws_query_parameter_3f2a692adb66481085449eb5db9619e2</sys_update_name><sys_updated_by>admin</sys_updated_by><sys_updated_on>2020-01-27 19:44:54</sys_updated_on><web_service_definition display_value="Ansible Inventory">8e95e962db66481085449eb5db961952</web_service_definition></sys_ws_query_parameter></record_update>]]></payload>
+<payload_hash>735828070</payload_hash>
+<remote_update_set display_value="Ansible_Inventory">674a39afdb220010081a3ec8f496197d</remote_update_set>
+<replace_on_upgrade>false</replace_on_upgrade>
+<sys_created_by>admin</sys_created_by>
+<sys_created_on>2020-01-30 23:28:31</sys_created_on>
+<sys_id>674a39afdb220010081a3ec8f496197e</sys_id>
+<sys_mod_count>0</sys_mod_count>
+<sys_recorded_at>16fe8890fae0000001</sys_recorded_at>
+<sys_updated_by>admin</sys_updated_by>
+<sys_updated_on>2020-01-30 23:28:31</sys_updated_on>
+<table/>
+<target_name>sysparm_fields</target_name>
+<type>Scripted REST Query Parameter</type>
+<update_domain>global</update_domain>
+<update_guid>625aed2ab966481080dc3bfae30dadbd</update_guid>
+<update_guid_history>625aed2ab966481080dc3bfae30dadbd:735828070,7f4ae92a586648109b769b2578bf6652:-407882821</update_guid_history>
+<update_set display_value=""/>
+<view/>
+</sys_update_xml>
+<sys_update_xml action="INSERT_OR_UPDATE">
+<action>INSERT_OR_UPDATE</action>
+<application display_value="Global">global</application>
+<category>customer</category>
+<comments/>
+<name>sys_ws_operation_20b521a2db66481085449eb5db96190f</name>
+<payload>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;record_update table="sys_ws_operation"&gt;&lt;sys_ws_operation action="INSERT_OR_UPDATE"&gt;&lt;active&gt;true&lt;/active&gt;&lt;consumes&gt;application/json,application/xml,text/xml&lt;/consumes&gt;&lt;consumes_customized&gt;false&lt;/consumes_customized&gt;&lt;default_operation_uri/&gt;&lt;enforce_acl&gt;cf9d01d3e73003009d6247e603f6a990&lt;/enforce_acl&gt;&lt;http_method&gt;GET&lt;/http_method&gt;&lt;name&gt;Ansible Inventory&lt;/name&gt;&lt;operation_script&gt;&lt;![CDATA[(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
+
+ function getRelatedSubCI(sys_id, target) {
+
+ var gp = [];
+ var a = sys_id; //current.cmdb_ci;
+
+ //cmdb_rel_ci has the relationship to child CIs
+ var grp = new GlideRecord('cmdb_rel_ci');
+ grp.addQuery(target, a);
+ grp.query();
+
+ var x = 0;
+ while (grp.next()) {
+ gp[x] = {};
+ target == 'parent' ? gp[x].ci_type = grp.child.sys_class_name.getDisplayValue() : gp[x].ci_type = grp.parent.sys_class_name.getDisplayValue();
+ gp[x].ci_rel_type = grp.type.getDisplayValue().replace(/\s|:/g, "_");
+ target == 'parent' ? gp[x].ci = grp.child.name : gp[x].ci = grp.parent.name;
+ x++;
+ }
+
+ return gp;
+ }
+
+ if (!request.queryParams.sysparm_fields) {
+ response.setStatus(400);
+ response.setContentType('application/json');
+ response.setError(new sn_ws_err.BadRequestError("no sysparm_fields query param"));
+ } else if (!request.queryParams.table) {
+ response.setStatus(400);
+ response.setContentType('application/json');
+ response.setError(new sn_ws_err.BadRequestError("no table specified"));
+ } else {
+
+ var queryString = "sysparm_exclude_reference_link=false&amp;sysparm_display_value=true&amp;sysparm_fields=" + request.queryParams.sysparm_fields + "&amp;sysparm_query";
+
+ var table = request.queryParams.table;
+
+ if (!/^cmdb_ci_/.test(table)) {
+ response.setStatus(400);
+ response.setContentType('application/json');
+ response.setError(new sn_ws_err.BadRequestError("table must be a child of cmdb_ci"));
+ } else if (!gs.tableExists(table)) {
+ response.setStatus(400);
+ response.setContentType('application/json');
+ response.setError(new sn_ws_err.BadRequestError("specified table "+table+" does not exist"));
+ } else {
+
+ var regexp = /^.+sysparm_fields\=(.*)\&amp;\w*/;
+ var fields = (queryString.match(regexp))[1].split(',');
+
+ var gr = new GlideRecord(table);
+ gr.addEncodedQuery(queryString);
+ gr.query();
+
+ var results = {
+ 'result': []
+ };
+ var i = 0;
+ var parent = {};
+ var child = {};
+
+ while (gr.next()) {
+
+ parent = getRelatedSubCI(gr.sys_id, 'parent');
+ child = getRelatedSubCI(gr.sys_id, 'child');
+ results['result'][i] = {
+ //'parent': parent.ci,
+ 'parent_relationships': parent,
+ //'child': child.ci,
+ 'child_relationships': child
+ };
+ for (y in fields) {
+ results['result'][i][fields[y]] = gr.getDisplayValue(fields[y]);
+ }
+ i++;
+ }
+ response.setContentType('application/json');
+ response.setStatus(200);
+ response.setBody(results.result);
+ }
+ }
+
+})(request, response);]]&gt;&lt;/operation_script&gt;&lt;operation_uri&gt;/api/snc/ansible_inventory&lt;/operation_uri&gt;&lt;produces&gt;application/json,application/xml,text/xml&lt;/produces&gt;&lt;produces_customized&gt;false&lt;/produces_customized&gt;&lt;relative_path&gt;/&lt;/relative_path&gt;&lt;request_example/&gt;&lt;requires_acl_authorization&gt;true&lt;/requires_acl_authorization&gt;&lt;requires_authentication&gt;true&lt;/requires_authentication&gt;&lt;requires_snc_internal_role&gt;false&lt;/requires_snc_internal_role&gt;&lt;short_description/&gt;&lt;sys_class_name&gt;sys_ws_operation&lt;/sys_class_name&gt;&lt;sys_created_by&gt;admin&lt;/sys_created_by&gt;&lt;sys_created_on&gt;2020-01-27 19:24:55&lt;/sys_created_on&gt;&lt;sys_customer_update&gt;false&lt;/sys_customer_update&gt;&lt;sys_id&gt;20b521a2db66481085449eb5db96190f&lt;/sys_id&gt;&lt;sys_mod_count&gt;50&lt;/sys_mod_count&gt;&lt;sys_name&gt;Ansible Inventory&lt;/sys_name&gt;&lt;sys_package display_value="Global" source="global"&gt;global&lt;/sys_package&gt;&lt;sys_policy/&gt;&lt;sys_replace_on_upgrade&gt;false&lt;/sys_replace_on_upgrade&gt;&lt;sys_scope display_value="Global"&gt;global&lt;/sys_scope&gt;&lt;sys_update_name&gt;sys_ws_operation_20b521a2db66481085449eb5db96190f&lt;/sys_update_name&gt;&lt;sys_updated_by&gt;admin&lt;/sys_updated_by&gt;&lt;sys_updated_on&gt;2020-01-27 21:15:10&lt;/sys_updated_on&gt;&lt;web_service_definition display_value="Ansible Inventory"&gt;8e95e962db66481085449eb5db961952&lt;/web_service_definition&gt;&lt;web_service_version/&gt;&lt;/sys_ws_operation&gt;&lt;/record_update&gt;</payload>
+<payload_hash>1074422118</payload_hash>
+<remote_update_set display_value="Ansible_Inventory">674a39afdb220010081a3ec8f496197d</remote_update_set>
+<replace_on_upgrade>false</replace_on_upgrade>
+<sys_created_by>admin</sys_created_by>
+<sys_created_on>2020-01-30 23:28:31</sys_created_on>
+<sys_id>a34a39afdb220010081a3ec8f496197e</sys_id>
+<sys_mod_count>0</sys_mod_count>
+<sys_recorded_at>16fe8dbb49b0000001</sys_recorded_at>
+<sys_updated_by>admin</sys_updated_by>
+<sys_updated_on>2020-01-30 23:28:31</sys_updated_on>
+<table/>
+<target_name>Ansible Inventory</target_name>
+<type>Scripted REST Resource</type>
+<update_domain>global</update_domain>
+<update_guid>0d0f3d669ae648105dfd0d683c641e24</update_guid>
+<update_guid_history>0d0f3d669ae648105dfd0d683c641e24:1074422118,856e3d66dae64810343768747a3e321f:1730035206,2e0d7da23fe64810af6f7cfc7e18ad32:-1757677024,664cb5a2dae648105756166f01c41b01:-725853184,4cfbbd6236e648102bad37a1a8234fc1:-208273856,3f6b75ee3fa64810dd4596b8a05625c5:1376315424,955a75ee01a648103b53906e8d3dce6d:430933392,4ef975eee6a648106c3381093f8f6068:1312994583,6fa979aebea6481056a80d7f5a93c575:1636415031,9b7935ae99a6481014c1a8db5451bf1e:914602057,6149f1ae05a64810f588ce90d381f8c4:861040761,47c8b16ecaa64810937cf992b8c7dbef:1332608858,45a8392ec7a64810a79053c31d076568:-1494029102,dd78392e7ca64810ec844c995635c762:542268540,c248392e63a64810ac8ac28574078c38:1768105004,fcd7b92ab3a64810ac2f06ca7ed15758:-528303117,7cb6352a46a648107e490d8685595ae8:75471988,da75752a62a64810a34bc5a8b4651c54:-463417776,3745f9e2f7a648100ae5536a30222939:42335310,30d4f9e61fa6481014d6462867a6942c:-722896322,d3c1f9e222a6481086744cb783d9222f:-1652078180,d46179a2b4a64810396ce345c7af2ac2:-1206689548,0401fd62fda64810160cf8660d193849:-1445231948,d36071ee8866481015a991c63d34c1a6:1000577296,1f6ea56e8f6648102d6d1fcd343ff4e9:-1291387353,1c6d292ee8664810fd96d8dae3cdd0cf:339933249,cd3da12eec664810da6b553cff9071a1:-1931992928,478c69eaff664810c4cbb2f0c55d1efa:-468812462,dd7c69eafd66481043397b64c941abf4:2128744305,7e1ced6a9a664810a8cbdfc72b691bb2:1435735615,3afb6daabf6648103a1b25780cea4656:760621217,918b6daa3f664810efa2299b5daeb851:432563560,11eaed2a066648105911d7a91b242fcf:194023943,42ca216aa7664810be678c16dbedd44a:2132295303,ebf9292a99664810c589e3532d8e8765:-2137588737,02b925e6366648102df9ea72713185cc:-690959945,5839e5a6cc664810967bf75cc69a1215:1463531592,b78825a60366481034c8238c6802af7a:1073365151,526821a6aa664810fc96b9d7f4683c88:-1304589235,fc5861a65a664810a5b30ae1cf7dab34:1045386951,8948ed668f664810b3dbca0553c0e873:746752488,20186966986648107f2f6eb6ca1e1f9b:2119584903,6bd76526dd664810faffa12178ac1b94:1044137095,06a7ad26f86648109a504183943216ba:-1064086520,d28765267d664810cb3c474a040e4ccf:-1800063027,7f472126ac664810a5d32e6fbf80c047:1699569421,60172de27a664810c931e012b3ea1a4b:-856412088,30f62de2a16648107fd0ce8ca70da25f:-1714083000,1ce625a2b1664810fb3910e6405dbd41:311127871,1a2625a20866481066e4e95eebb61146:653669429,0ec525a24666481068bfb434beebdb04:924471465</update_guid_history>
+<update_set display_value=""/>
+<view/>
+</sys_update_xml>
+<sys_update_xml action="INSERT_OR_UPDATE">
+<action>INSERT_OR_UPDATE</action>
+<application display_value="Global">global</application>
+<category>customer</category>
+<comments/>
+<name>sys_ws_definition_8e95e962db66481085449eb5db961952</name>
+<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_ws_definition"><sys_ws_definition action="INSERT_OR_UPDATE"><active>true</active><base_uri>/api/snc/ansible_inventory</base_uri><consumes>application/json,application/xml,text/xml</consumes><consumes_customized>false</consumes_customized><default_version>No active default version</default_version><doc_link/><enforce_acl>cf9d01d3e73003009d6247e603f6a990</enforce_acl><is_versioned>false</is_versioned><name>Ansible Inventory</name><namespace>snc</namespace><produces>application/json,application/xml,text/xml</produces><produces_customized>false</produces_customized><service_id>ansible_inventory</service_id><short_description/><sys_class_name>sys_ws_definition</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2020-01-27 19:24:14</sys_created_on><sys_customer_update>false</sys_customer_update><sys_id>8e95e962db66481085449eb5db961952</sys_id><sys_mod_count>1</sys_mod_count><sys_name>Ansible Inventory</sys_name><sys_package display_value="Global" source="global">global</sys_package><sys_policy/><sys_replace_on_upgrade>false</sys_replace_on_upgrade><sys_scope display_value="Global">global</sys_scope><sys_update_name>sys_ws_definition_8e95e962db66481085449eb5db961952</sys_update_name><sys_updated_by>admin</sys_updated_by><sys_updated_on>2020-01-27 19:24:29</sys_updated_on></sys_ws_definition></record_update>]]></payload>
+<payload_hash>740685616</payload_hash>
+<remote_update_set display_value="Ansible_Inventory">674a39afdb220010081a3ec8f496197d</remote_update_set>
+<replace_on_upgrade>false</replace_on_upgrade>
+<sys_created_by>admin</sys_created_by>
+<sys_created_on>2020-01-30 23:28:31</sys_created_on>
+<sys_id>eb4a39afdb220010081a3ec8f496197d</sys_id>
+<sys_mod_count>0</sys_mod_count>
+<sys_recorded_at>16fe8765f720000001</sys_recorded_at>
+<sys_updated_by>admin</sys_updated_by>
+<sys_updated_on>2020-01-30 23:28:31</sys_updated_on>
+<table/>
+<target_name>Ansible Inventory</target_name>
+<type>Scripted REST API</type>
+<update_domain>global</update_domain>
+<update_guid>2ba5ad625e664810987a1cee2ddbb698</update_guid>
+<update_guid_history>2ba5ad625e664810987a1cee2ddbb698:740685616,08a56d6278664810ea559a69b459e3d0:-1084756942</update_guid_history>
+<update_set display_value=""/>
+<view/>
+</sys_update_xml>
+</unload>