summaryrefslogtreecommitdiffstats
path: root/ansible_collections/sensu/sensu_go/plugins/modules
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 16:03:42 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 16:03:42 +0000
commit66cec45960ce1d9c794e9399de15c138acb18aed (patch)
tree59cd19d69e9d56b7989b080da7c20ef1a3fe2a5a /ansible_collections/sensu/sensu_go/plugins/modules
parentInitial commit. (diff)
downloadansible-66cec45960ce1d9c794e9399de15c138acb18aed.tar.xz
ansible-66cec45960ce1d9c794e9399de15c138acb18aed.zip
Adding upstream version 7.3.0+dfsg.upstream/7.3.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/sensu/sensu_go/plugins/modules')
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/ad_auth_provider.py396
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/asset.py213
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/asset_info.py99
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/auth_provider_info.py145
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/bonsai_asset.py131
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/check.py449
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/check_info.py97
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/cluster.py116
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/cluster_info.py101
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/cluster_role.py164
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_binding.py145
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_binding_info.py97
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_info.py98
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/datastore.py170
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/datastore_info.py104
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/entity.py261
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/entity_info.py125
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/etcd_replicator.py218
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/etcd_replicator_info.py104
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/event.py335
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/event_info.py142
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/filter.py158
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/filter_info.py93
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/handler_info.py94
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/handler_set.py119
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/hook.py149
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/hook_info.py95
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/ldap_auth_provider.py378
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/mutator.py154
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/mutator_info.py96
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/namespace.py87
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/namespace_info.py79
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/oidc_auth_provider.py248
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/pipe_handler.py167
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/role.py165
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/role_binding.py176
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/role_binding_info.py97
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/role_info.py100
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/secret.py131
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/secret_info.py110
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_env.py98
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_info.py111
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_vault.py258
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/silence.py172
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/silence_info.py112
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/socket_handler.py160
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/tessen.py108
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/user.py326
-rw-r--r--ansible_collections/sensu/sensu_go/plugins/modules/user_info.py90
49 files changed, 7841 insertions, 0 deletions
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/ad_auth_provider.py b/ansible_collections/sensu/sensu_go/plugins/modules/ad_auth_provider.py
new file mode 100644
index 00000000..609b16cb
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/ad_auth_provider.py
@@ -0,0 +1,396 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2020, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: ad_auth_provider
+
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Miha Dolinar (@mdolin)
+ - Tadej Borovsak (@tadeboro)
+
+short_description: Manage Sensu AD authentication provider
+
+description:
+ - Create, update or delete a Sensu Go AD authentication provider.
+ - For more information, refer to the Sensu Go documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/control-access/ad-auth/).
+
+version_added: 1.10.0
+
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.state
+
+options:
+ servers:
+ description:
+ - An array of AD servers for your directory.
+ type: list
+ elements: dict
+ suboptions:
+ host:
+ description:
+ - AD server IP address.
+ required: true
+ type: str
+ port:
+ description:
+ - AD server port.
+ type: int
+ insecure:
+ description:
+ - Skips SSL certificate verification when set to true.
+ type: bool
+ default: false
+ security:
+ description:
+ - Encryption type to be used for the connection to the AD server.
+ type: str
+ choices: [ insecure, tls, starttls ]
+ default: tls
+ trusted_ca_file:
+ description:
+ - Path to an alternative CA bundle file.
+ type: str
+ client_cert_file:
+ description:
+ - Path to the certificate that should be sent to the server if requested.
+ type: str
+ client_key_file:
+ description:
+ - Path to the key file associated with the client_cert_file.
+ - Required if I(client_cert_file) is present.
+ type: str
+ default_upn_domain:
+ description:
+ - Enables UPN authentication when set. The default UPN suffix that will be appended
+ to the username when a domain is not specified during login
+ (for example, user becomes user@defaultdomain.xyz).
+ type: str
+ include_nested_groups:
+ description:
+ - If true, the group search includes any nested groups a user is a member of.
+ If false, the group search includes only the top-level groups a user is a member of.
+ type: bool
+ binding:
+ description:
+ - The AD account that performs user and group lookups.
+ - If your sever supports anonymous binding, you can omit the user_dn or password
+ attributes to query the directory without credentials.
+ type: dict
+ suboptions:
+ user_dn:
+ description:
+ - The AD account that performs user and group lookups.
+ - If your sever supports anonymous binding, you can omit this attribute.
+ type: str
+ required: true
+ password:
+ description:
+ - Password for the user_dn account.
+ - If your sever supports anonymous binding, you can omit this attribute.
+ type: str
+ required: true
+ group_search:
+ description:
+ - Search configuration for groups.
+ type: dict
+ suboptions:
+ base_dn:
+ description:
+ - Which part of the directory tree to search.
+ required: true
+ type: str
+ attribute:
+ description:
+ - Used for comparing result entries.
+ type: str
+ default: member
+ name_attribute:
+ description:
+ - Represents the attribute to use as the entry name.
+ type: str
+ default: cn
+ object_class:
+ description:
+ - Identifies the class of objects returned in the search result.
+ type: str
+ default: group
+ user_search:
+ description:
+ - Search configuration for users.
+ type: dict
+ suboptions:
+ base_dn:
+ description:
+ - Which part of the directory tree to search.
+ required: true
+ type: str
+ attribute:
+ description:
+ - Used for comparing result entries.
+ type: str
+ default: sAMAccountName
+ name_attribute:
+ description:
+ - Represents the attribute to use as the entry name.
+ type: str
+ default: displayName
+ object_class:
+ description:
+ - Identifies the class of objects returned in the search result.
+ type: str
+ default: person
+ groups_prefix:
+ description:
+ - The prefix added to all AD groups.
+ type: str
+ username_prefix:
+ description:
+ - The prefix added to all AD usernames.
+ type: str
+
+seealso:
+ - module: sensu.sensu_go.auth_provider_info
+ - module: sensu.sensu_go.ldap_auth_provider
+ - module: sensu.sensu_go.oidc_auth_provider
+"""
+
+EXAMPLES = """
+- name: Create a AD auth provider
+ sensu.sensu_go.ad_auth_provider:
+ name: activedirectory
+ servers:
+ - host: 127.0.0.1
+ group_search:
+ base_dn: dc=acme,dc=org
+ user_search:
+ base_dn: dc=acme,dc=org
+- name: Delete a AD auth provider
+ sensu.sensu_go.ad_auth_provider:
+ name: activedirectory
+ state: absent
+"""
+
+RETURN = """
+object:
+ description: Object representing Sensu AD authentication provider.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: 'activedirectory'
+ servers:
+ host: '127.0.0.1'
+ port: '636'
+ insecure: 'False'
+ security: 'tls'
+ trusted_ca_file: '/path/to/trusted-certificate-authorities.pem'
+ client_cert_file: '/path/to/ssl/cert.pem'
+ client_key_file: '/path/to/ssl/key.pem'
+ default_upn_domain: 'example.org'
+ binding:
+ user_dn: 'cn=binder,dc=acme,dc=org'
+ group_search:
+ base_dn: 'dc=acme,dc=org'
+ attribute: 'member'
+ name_attribute': 'cn'
+ object_class: 'group'
+ user_search:
+ base_dn: 'dc=acme,dc=org'
+ attribute: 'sAMAccountName'
+ name_attribute: 'displayName'
+ object_class: 'person'
+ groups_prefix: 'AD'
+ username_prefix: 'AD'
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "authentication/v2"
+
+
+def remove_item(result):
+ if result:
+ for server in result["servers"]:
+ if server["binding"] and "password" in server["binding"]:
+ del server["binding"]["password"]
+
+ return result
+
+
+def _filter(payload):
+ # Remove keys with None values from dict
+ return dict((k, v) for k, v in payload.items() if v is not None)
+
+
+def do_differ(current, desired):
+ if utils.do_differ_v1(current, desired, "servers"):
+ return True
+
+ if len(current["spec"]["servers"]) != len(desired["spec"]["servers"]):
+ return True
+
+ for c, d in zip(current["spec"]["servers"], desired["spec"]["servers"]):
+ if utils.do_differ(c, _filter(d)):
+ return True
+
+ return False
+
+
+def main():
+ required_if = [("state", "present", ["servers"])]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth",
+ "name",
+ "state",
+ ),
+ servers=dict(
+ type="list",
+ elements="dict",
+ options=dict(
+ host=dict(
+ type="str",
+ required=True,
+ ),
+ port=dict(
+ type="int",
+ ),
+ insecure=dict(
+ type="bool",
+ default=False,
+ ),
+ security=dict(
+ type="str",
+ choices=["insecure", "tls", "starttls"],
+ default="tls",
+ ),
+ trusted_ca_file=dict(
+ type="str",
+ ),
+ client_cert_file=dict(
+ type="str",
+ ),
+ client_key_file=dict(
+ type="str",
+ ),
+ default_upn_domain=dict(
+ type="str",
+ ),
+ include_nested_groups=dict(
+ type="bool",
+ ),
+ binding=dict(
+ type="dict",
+ options=dict(
+ user_dn=dict(
+ type="str",
+ required=True,
+ ),
+ password=dict(
+ type="str",
+ no_log=True,
+ required=True,
+ ),
+ ),
+ ),
+ group_search=dict(
+ type="dict",
+ options=dict(
+ base_dn=dict(
+ type="str",
+ required=True,
+ ),
+ attribute=dict(
+ type="str",
+ default="member",
+ ),
+ name_attribute=dict(
+ type="str",
+ default="cn",
+ ),
+ object_class=dict(type="str", default="group"),
+ ),
+ ),
+ user_search=dict(
+ type="dict",
+ options=dict(
+ base_dn=dict(
+ type="str",
+ required=True,
+ ),
+ attribute=dict(
+ type="str",
+ default="sAMAccountName",
+ ),
+ name_attribute=dict(
+ type="str",
+ default="displayName",
+ ),
+ object_class=dict(
+ type="str",
+ default="person",
+ ),
+ ),
+ ),
+ ),
+ ),
+ groups_prefix=dict(
+ type="str",
+ ),
+ username_prefix=dict(
+ type="str",
+ ),
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, "authproviders", module.params["name"]
+ )
+
+ payload = dict(
+ type="ad",
+ api_version=API_VERSION,
+ metadata=dict(name=module.params["name"]),
+ spec=arguments.get_spec_payload(
+ module.params, "servers", "groups_prefix", "username_prefix"
+ ),
+ )
+
+ try:
+ changed, ad_provider = utils.sync_v1(
+ module.params["state"], client, path, payload, module.check_mode, do_differ
+ )
+ module.exit_json(changed=changed, object=remove_item(ad_provider))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/asset.py b/ansible_collections/sensu/sensu_go/plugins/modules/asset.py
new file mode 100644
index 00000000..627bfabb
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/asset.py
@@ -0,0 +1,213 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Cameron Hurst <cahurst@cisco.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: asset
+author:
+ - Cameron Hurst (@wakemaster39)
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu assets
+description:
+ - Create, update or delete Sensu Go asset.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/assets/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+ - sensu.sensu_go.labels
+ - sensu.sensu_go.annotations
+seealso:
+ - module: sensu.sensu_go.asset_info
+ - module: sensu.sensu_go.bonsai_asset
+options:
+ builds:
+ description:
+ - A list of asset builds used to define multiple artefacts which
+ provide the named asset.
+ - Required if I(state) is C(present).
+ type: list
+ elements: dict
+ suboptions:
+ url:
+ description:
+ - The URL location of the asset.
+ type: str
+ required: yes
+ sha512:
+ description:
+ - The checksum of the asset.
+ type: str
+ required: yes
+ filters:
+ description:
+ - A set of Sensu query expressions used to determine if the asset
+ should be installed.
+ type: list
+ elements: str
+ headers:
+ description:
+ - Additional headers to send when retrieving the asset, e.g. for
+ authorization.
+ type: dict
+"""
+
+EXAMPLES = """
+- name: Create a multiple-build asset
+ sensu.sensu_go.asset:
+ name: sensu-plugins-cpu-checks
+ builds:
+ - url: https://assets.bonsai.sensu.io/68546e739d96fd695655b77b35b5aabfbabeb056/sensu-plugins-cpu-checks_4.0.0_centos_linux_amd64.tar.gz
+ sha512: 518e7c17cf670393045bff4af318e1d35955bfde166e9ceec2b469109252f79043ed133241c4dc96501b6636a1ec5e008ea9ce055d1609865635d4f004d7187b
+ filters:
+ - entity.system.os == 'linux'
+ - entity.system.arch == 'amd64'
+ - entity.system.platform == 'rhel'
+ - url: https://assets.bonsai.sensu.io/68546e739d96fd695655b77b35b5aabfbabeb056/sensu-plugins-cpu-checks_4.0.0_alpine_linux_amd64.tar.gz
+ sha512: b2da25ecd7642e6de41fde37d674fe19dcb6ee3d680e145e32289f7cfc352e6b5f9413ee9b701d61faeaa47b399aa30b25885dbc1ca432c4061c8823774c28f3
+ filters:
+ - entity.system.os == 'linux'
+ - entity.system.arch == 'amd64'
+ - entity.system.platform == 'alpine'
+
+- name: Delete an asset
+ sensu.sensu_go.asset:
+ name: sensu-plugins-cpu-check
+ state: absent
+"""
+
+RETURN = """
+object:
+ description: Object representing Sensu asset.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: check_script
+ namespace: default
+ builds:
+ - sha512: 4f926bf4328f...2c58ad9ab40c9e2edc31b288d066b195b21b
+ url: http://example.com/asset.tar.gz
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def validate_module_params(params):
+ if params["state"] == "present":
+ if not params['builds']:
+ return "builds must include at least one element"
+ return None
+
+
+def _build_set(builds):
+ return set((
+ b.get('sha512'),
+ b.get('url'),
+ frozenset((b.get('headers', {}) or {}).items()),
+ frozenset(b.get('filters', []) or []),
+ ) for b in builds)
+
+
+def _do_builds_differ(current, desired):
+ # Since Sensu Go 5.16, the web API returns builds: None if the asset
+ # in question is a deprecated, single-build asset.
+ if current is None:
+ return True
+
+ if len(current) != len(desired):
+ return True
+
+ return _build_set(current) != _build_set(desired)
+
+
+def do_differ(current, desired):
+ if _do_builds_differ(current['builds'], desired['builds']):
+ return True
+
+ return utils.do_differ(current, desired, 'builds')
+
+
+def build_api_payload(params):
+ payload = arguments.get_mutation_payload(params)
+ if params['state'] == 'present':
+ builds = [arguments.get_spec_payload(b, *b.keys()) for b in params['builds']]
+ payload["builds"] = builds
+ return payload
+
+
+def main():
+ required_if = [
+ ("state", "present", ["builds"])
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth", "name", "namespace", "state", "labels", "annotations",
+ ),
+ builds=dict(
+ type="list",
+ elements="dict",
+ options=dict(
+ url=dict(
+ required=True,
+ ),
+ sha512=dict(
+ required=True,
+ ),
+ filters=dict(
+ type="list",
+ elements="str",
+ ),
+ headers=dict(
+ type="dict",
+ ),
+ )
+ ),
+ ),
+ )
+
+ msg = validate_module_params(module.params)
+ if msg:
+ module.fail_json(msg=msg)
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "assets", module.params["name"],
+ )
+ payload = build_api_payload(module.params)
+
+ try:
+ changed, asset = utils.sync(
+ module.params["state"], client, path, payload, module.check_mode, do_differ
+ )
+ module.exit_json(changed=changed, object=asset)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/asset_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/asset_info.py
new file mode 100644
index 00000000..3c128dcb
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/asset_info.py
@@ -0,0 +1,99 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: asset_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu assets
+description:
+ - Retrieve information about Sensu Go assets.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/assets/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.asset
+ - module: sensu.sensu_go.bonsai_asset
+"""
+
+EXAMPLES = """
+- name: List all Sensu assets
+ sensu.sensu_go.asset_info:
+ register: result
+
+- name: List the selected Sensu asset
+ sensu.sensu_go.asset_info:
+ name: my_asset
+ register: result
+
+- name: Do something with result
+ ansible.builtin.debug:
+ msg: "{{ result.objects.0.metadata.name }}"
+
+"""
+
+RETURN = """
+objects:
+ description: List of Sensu assets.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: check_script
+ namespace: default
+ builds:
+ - sha512: 4f926bf4328f...2c58ad9ab40c9e2edc31b288d066b195b21b
+ url: http://example.com/asset.tar.gz
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "assets", module.params["name"],
+ )
+
+ try:
+ assets = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=assets)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/auth_provider_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/auth_provider_info.py
new file mode 100644
index 00000000..6215af44
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/auth_provider_info.py
@@ -0,0 +1,145 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2020, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: auth_provider_info
+
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Miha Dolinar (@mdolin)
+ - Tadej Borovsak (@tadeboro)
+
+short_description: List Sensu authentication providers
+
+description:
+ - Retrieve information about Sensu Go authentication providers.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/control-access/).
+
+version_added: 1.10.0
+
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+
+seealso:
+ - module: sensu.sensu_go.ad_auth_provider
+ - module: sensu.sensu_go.ldap_auth_provider
+ - module: sensu.sensu_go.oidc_auth_provider
+"""
+
+EXAMPLES = """
+- name: List all Sensu authentication providers
+ sensu.sensu_go.auth_provider_info:
+ register: result
+
+- name: List the selected Sensu authentication provider
+ sensu.sensu_go.auth_provider_info:
+ name: my_auth_provider
+ register: result
+
+- name: Do something with result
+ ansible.builtin.debug:
+ msg: "{{ result.objects.0.metadata.name }}"
+"""
+
+RETURN = """
+objects:
+ description: List of Sensu authentication providers.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: 'openldap'
+ groups_prefix: ''
+ servers:
+ binding:
+ user_dn: 'cn=binder,dc=acme,dc=org'
+ client_cert_file: ''
+ client_key_file: ''
+ default_upn_domain: ''
+ group_search:
+ attribute: 'member'
+ base_dn: 'dc=acme,dc=org'
+ name_attribute: 'cn'
+ object_class: 'groupOfNames'
+ host: '127.0.0.1'
+ insecure: false
+ port: 636
+ security: 'tls'
+ trusted_ca_file: ''
+ user_search:
+ attribute: 'uid'
+ base_dn: 'dc=acme,dc=org'
+ name_attribute: 'cn'
+ object_class: 'person'
+ username_prefix: ''
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "authentication/v2"
+
+
+def remove_item(result):
+ for server in result.get("servers", []):
+ if server["binding"] and "password" in server["binding"]:
+ del server["binding"]["password"]
+
+ if "client_secret" in result:
+ del result["client_secret"]
+
+ return result
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP,
+ API_VERSION,
+ None,
+ "authproviders",
+ module.params["name"],
+ )
+
+ try:
+ providers = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ # We simulate the behavior of v2 API here and only return the spec.
+ module.exit_json(
+ changed=False,
+ objects=[remove_item(utils.convert_v1_to_v2_response(p)) for p in providers],
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/bonsai_asset.py b/ansible_collections/sensu/sensu_go/plugins/modules/bonsai_asset.py
new file mode 100644
index 00000000..417218ec
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/bonsai_asset.py
@@ -0,0 +1,131 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: bonsai_asset
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Tadej Borovsak (@tadeboro)
+short_description: Add Sensu assets from Bonsai
+description:
+ - Create or update a Sensu Go asset whose definition is available in the
+ Bonsai, the Sensu asset index.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/assets/)
+ and U(https://bonsai.sensu.io/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.labels
+ - sensu.sensu_go.annotations
+options:
+ version:
+ description:
+ - Version number of the asset to install.
+ type: str
+ required: true
+ rename:
+ description:
+ - The name that will be used when adding the asset to Sensu.
+ - If not present, value of the I(name) parameter will be used.
+ type: str
+ on_remote:
+ description:
+ - If set to C(true), module will download asset defnition on remote host.
+ - If not set or set to C(false), ansible downloads asset definition
+ on control node.
+ type: bool
+ version_added: 1.13.0
+notes:
+ - I(labels) and I(annotations) values are merged with the values obtained
+ from Bonsai. Values passed-in as parameters take precedence over the
+ values obtained from Bonsai.
+ - To delete an asset, use regular M(sensu.sensu_go.asset) module.
+seealso:
+ - module: sensu.sensu_go.asset
+ - module: sensu.sensu_go.asset_info
+"""
+
+EXAMPLES = """
+- name: Make sure specific version of asset is installed
+ sensu.sensu_go.bonsai_asset:
+ name: sensu/monitoring-plugins
+ version: 2.2.0-1
+
+- name: Remove previously added asset
+ sensu.sensu_go.asset:
+ name: sensu/monitoring-plugins
+ state: absent
+
+- name: Store Bonsai asset under a different name
+ sensu.sensu_go.bonsai_asset:
+ name: sensu/monitoring-plugins
+ version: 2.2.0-1
+ rename: sensu-monitoring-2.2.0-1
+
+- name: Display asset info
+ sensu.sensu_go.asset_info:
+ name: sensu-monitoring-2.2.0-1 # value from rename field
+"""
+
+RETURN = """
+object:
+ description: Object representing Sensu asset.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: check_script
+ namespace: default
+ builds:
+ - sha512: 4f926bf4328f...2c58ad9ab40c9e2edc31b288d066b195b21b
+ url: http://example.com/asset.tar.gz
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import bonsai, errors
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ name=dict(
+ type="str",
+ required=True,
+ ),
+ version=dict(
+ type="str",
+ required=True,
+ ),
+ ),
+ )
+
+ try:
+ asset = bonsai.get_asset_parameters(
+ module.params["name"], module.params["version"],
+ )
+ module.exit_json(changed=False, asset=asset)
+ except errors.Error as e:
+ module.fail_json(changed=False, msg=str(e))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/check.py b/ansible_collections/sensu/sensu_go/plugins/modules/check.py
new file mode 100644
index 00000000..47f44693
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/check.py
@@ -0,0 +1,449 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: check
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu checks
+description:
+ - Create, update or delete Sensu Go check.
+ - For more information, refer to the Sensu Go documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/checks/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+ - sensu.sensu_go.labels
+ - sensu.sensu_go.annotations
+ - sensu.sensu_go.secrets
+seealso:
+ - module: sensu.sensu_go.check_info
+options:
+ command:
+ description:
+ - Check command to run.
+ - Required if I(state) is C(present).
+ type: str
+ subscriptions:
+ description:
+ - List of subscriptions which receive check requests.
+ - Required if I(state) is C(present).
+ type: list
+ elements: str
+ handlers:
+ description:
+ - List of handlers which receive check results.
+ type: list
+ elements: str
+ interval:
+ description:
+ - Check request interval.
+ - Cannot be used when I(cron) option is used.
+ type: int
+ cron:
+ description:
+ - Schedule check requests using crontab syntax.
+ - Cannot be used when I(interval) option is used.
+ type: str
+ publish:
+ description:
+ - Enables or disables scheduled publication of check requests.
+ type: bool
+ timeout:
+ description:
+ - Check execution timeout.
+ type: int
+ ttl:
+ description:
+ - Amount of time after which a check result is considered stale.
+ type: int
+ stdin:
+ description:
+ - Enables writing of serialized JSON data to the check command's stdin.
+ - Only usable with checks written specifically for Sensu Go.
+ type: bool
+ low_flap_threshold:
+ description:
+ - Low flap threshold.
+ type: int
+ high_flap_threshold:
+ description:
+ - High flap threshold.
+ type: int
+ runtime_assets:
+ description:
+ - List of runtime assets required to run the check.
+ type: list
+ elements: str
+ check_hooks:
+ description:
+ - A mapping of response codes to hooks which will be run by the agent
+ when that code is returned.
+ - Note that the structure of this parameter is a bit different from the
+ one described at
+ U(https://docs.sensu.io/sensu-go/latest/reference/checks/#check-hooks-attribute).
+ - See check hooks example below for more information on exact mapping
+ structure.
+ type: dict
+ proxy_entity_name:
+ description:
+ - Entity name to associate this check with instead of the agent it ran on.
+ type: str
+ proxy_requests:
+ description:
+ - Allows you to assign the check to run for multiple entities according
+ to their entity_attributes.
+ type: dict
+ suboptions:
+ entity_attributes:
+ description:
+ - List of attribute checks for determining which proxy entities this check should be scheduled against.
+ type: list
+ elements: str
+ splay:
+ description:
+ - Enables or disables splaying of check request scheduling.
+ type: bool
+ splay_coverage:
+ description:
+ - Percentage of the C(interval) over which to splay checks.
+ type: int
+ output_metric_format:
+ description:
+ - Enable parsing of metrics in the specified format from this check's
+ output.
+ type: str
+ choices:
+ - graphite_plaintext
+ - influxdb_line
+ - nagios_perfdata
+ - opentsdb_line
+ output_metric_handlers:
+ description:
+ - List of handlers which receive check results. I'm not sure why this exists.
+ type: list
+ elements: str
+ round_robin:
+ description:
+ - An array of environment variables to use with command execution.
+ type: bool
+ env_vars:
+ description:
+ - A mapping of environment variable names and values to use with command execution.
+ type: dict
+'''
+
+EXAMPLES = '''
+- name: Check executing command every 30 seconds
+ sensu.sensu_go.check:
+ name: check
+ command: check-cpu.sh -w 75 -c 90
+ subscriptions:
+ - checks
+ interval: 30
+ publish: yes
+
+- name: Check executing command with cron scheduler
+ sensu.sensu_go.check:
+ name: check
+ command: check-cpu.sh -w 75 -c 90
+ subscriptions:
+ - systems
+ handlers:
+ - slack
+ cron: "* * * * *"
+ publish: yes
+
+- name: Ad-hoc scheduling
+ sensu.sensu_go.check:
+ name: check
+ command: check-cpu.sh -w 75 -c 90
+ subscriptions:
+ - systems
+ handlers:
+ - slack
+ interval: 60
+ publish: no
+
+- name: Report events under proxy entity name instead of agent entity
+ sensu.sensu_go.check:
+ name: check
+ command: http_check.sh https://sensu.io
+ subscriptions:
+ - proxy
+ handlers:
+ - slack
+ interval: 60
+ proxy_entity_name: sensu-site
+ round_robin: yes
+ publish: yes
+
+- name: Event that triggers hooks
+ sensu.sensu_go.check:
+ name: check
+ command: http_check.sh https://sensu.io
+ subscriptions: [ proxy ]
+ # The upstream JSON payload for the hooks below would look like this:
+ #
+ # "check_hooks": [
+ # {"0": ["passing-hook", "always-run-this-hook"]},
+ # {"critical": ["failing-hook", "always-run-this-hook"]}
+ # ]
+ #
+ # Ansible task simplifies this structure into a simple mapping:
+ check_hooks:
+ "0":
+ - passing-hook
+ - always-run-this-hook
+ critical:
+ - failing-hook
+ - always-run-this-hook
+
+- name: Remove check
+ sensu.sensu_go.check:
+ name: my-check
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu check.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: check_minimum
+ namespace: default
+ command: collect.sh
+ handlers:
+ - slack
+ interval: 10
+ publish: true
+ subscriptions:
+ - system
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def validate_module_params(module):
+ params = module.params
+ proxy_requests = params['proxy_requests']
+
+ if (proxy_requests and proxy_requests.get('splay', False) and
+ proxy_requests.get('splay_coverage') is None):
+ module.fail_json(msg='splay is true but all of the following are missing: splay_coverage')
+
+ if params['state'] == 'present' and not (params['interval'] or params['cron']):
+ module.fail_json(msg='one of the following is required: interval, cron')
+
+
+def do_sets_differ(current, desired, key):
+ return set(current.get(key) or []) != set(desired.get(key) or [])
+
+
+def do_proxy_requests_differ(current, desired):
+ if 'proxy_requests' not in desired:
+ return False
+
+ current = current.get('proxy_requests') or {}
+ desired = desired['proxy_requests']
+
+ return (
+ (
+ 'entity_attributes' in desired and
+ do_sets_differ(current, desired, 'entity_attributes')
+ ) or
+ utils.do_differ(current, desired, 'entity_attributes')
+ )
+
+
+def do_check_hooks_differ(current, desired):
+ if 'check_hooks' not in desired:
+ return False
+
+ current = utils.single_item_dicts_to_dict(current.get('check_hooks') or [])
+ current = dict((k, set(v)) for k, v in current.items())
+
+ desired = utils.single_item_dicts_to_dict(desired['check_hooks'])
+ desired = dict((k, set(v)) for k, v in desired.items())
+
+ return current != desired
+
+
+def do_differ(current, desired):
+ return (
+ utils.do_differ(
+ current, desired, 'proxy_requests', 'subscriptions', 'handlers',
+ 'runtime_assets', 'check_hooks', 'output_metric_handlers',
+ 'env_vars', 'secrets',
+ ) or
+ utils.do_secrets_differ(current, desired) or
+ do_proxy_requests_differ(current, desired) or
+ do_sets_differ(current, desired, 'subscriptions') or
+ do_sets_differ(current, desired, 'handlers') or
+ do_sets_differ(current, desired, 'runtime_assets') or
+ do_check_hooks_differ(current, desired) or
+ do_sets_differ(current, desired, 'output_metric_handlers') or
+ do_sets_differ(current, desired, 'env_vars')
+ )
+
+
+def build_api_payload(params):
+ payload = arguments.get_mutation_payload(
+ params,
+ 'command',
+ 'cron',
+ 'handlers',
+ 'high_flap_threshold',
+ 'interval',
+ 'low_flap_threshold',
+ 'output_metric_format',
+ 'output_metric_handlers',
+ 'proxy_entity_name',
+ 'publish',
+ 'round_robin',
+ 'runtime_assets',
+ 'secrets',
+ 'stdin',
+ 'subscriptions',
+ 'timeout',
+ 'ttl'
+ )
+
+ if params['proxy_requests']:
+ payload['proxy_requests'] = arguments.get_spec_payload(
+ params['proxy_requests'],
+ 'entity_attributes', 'splay', 'splay_coverage',
+ )
+
+ if params['check_hooks']:
+ payload['check_hooks'] = utils.dict_to_single_item_dicts(params['check_hooks'])
+
+ if params['env_vars']:
+ payload['env_vars'] = utils.dict_to_key_value_strings(params['env_vars'])
+
+ return payload
+
+
+def main():
+ required_if = [
+ ('state', 'present', ['subscriptions', 'command'])
+ ]
+ mutually_exclusive = [('interval', 'cron')]
+
+ module = AnsibleModule(
+ supports_check_mode=True,
+ required_if=required_if,
+ mutually_exclusive=mutually_exclusive,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth", "name", "state", "labels", "annotations", "namespace",
+ "secrets",
+ ),
+ command=dict(),
+ subscriptions=dict(
+ type='list', elements='str',
+ ),
+ handlers=dict(
+ type='list', elements='str',
+ ),
+ interval=dict(
+ type='int'
+ ),
+ cron=dict(),
+ publish=dict(
+ type='bool'
+ ),
+ timeout=dict(
+ type='int'
+ ),
+ ttl=dict(
+ type='int'
+ ),
+ stdin=dict(
+ type='bool'
+ ),
+ env_vars=dict(
+ type='dict'
+ ),
+ low_flap_threshold=dict(
+ type='int'
+ ),
+ high_flap_threshold=dict(
+ type='int'
+ ),
+ runtime_assets=dict(
+ type='list', elements='str',
+ ),
+ check_hooks=dict(
+ type='dict'
+ ),
+ proxy_entity_name=dict(),
+ proxy_requests=dict(
+ type='dict',
+ options=dict(
+ entity_attributes=dict(
+ type='list', elements='str',
+ ),
+ splay=dict(
+ type='bool'
+ ),
+ splay_coverage=dict(
+ type='int'
+ )
+ )
+ ),
+ output_metric_format=dict(
+ choices=['nagios_perfdata', 'graphite_plaintext', 'influxdb_line', 'opentsdb_line']
+ ),
+ output_metric_handlers=dict(
+ type='list', elements='str',
+ ),
+ round_robin=dict(
+ type='bool'
+ )
+ )
+ )
+ validate_module_params(module)
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ module.params['namespace'], 'checks', module.params['name'],
+ )
+ payload = build_api_payload(module.params)
+
+ try:
+ changed, check = utils.sync(
+ module.params['state'], client, path, payload, module.check_mode,
+ do_differ,
+ )
+ module.exit_json(changed=changed, object=check)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/check_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/check_info.py
new file mode 100644
index 00000000..3bb207c9
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/check_info.py
@@ -0,0 +1,97 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: check_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu checks
+description:
+ - Retrieve information about Sensu Go checks.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/checks/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.check
+'''
+
+EXAMPLES = '''
+- name: List all Sensu checks
+ sensu.sensu_go.check_info:
+ register: result
+
+- name: Obtain a specific check
+ sensu.sensu_go.check_info:
+ name: my-check
+ register: result
+'''
+
+RETURN = '''
+objects:
+ description: List of Sensu checks.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: check_minimum
+ namespace: default
+ command: collect.sh
+ handlers:
+ - slack
+ interval: 10
+ publish: true
+ subscriptions:
+ - system
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "checks", module.params["name"],
+ )
+
+ try:
+ checks = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=checks)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/cluster.py b/ansible_collections/sensu/sensu_go/plugins/modules/cluster.py
new file mode 100644
index 00000000..a75fbbe2
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/cluster.py
@@ -0,0 +1,116 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2021, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: cluster
+author:
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu Go clusters
+description:
+ - Create, update or delete Sensu cluster.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/deploy-sensu/cluster-sensu/).
+version_added: 1.9.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.state
+seealso:
+ - module: sensu.sensu_go.cluster_info
+options:
+ api_urls:
+ description:
+ - List of API urls that compose a single cluster.
+ - Required if I(state) is C(present).
+ type: list
+ elements: str
+"""
+
+EXAMPLES = """
+- name: Create a small cluster
+ sensu.sensu_go.cluster:
+ name: small-cluster
+ api_urls: https://sensu.alpha.example.com:8080
+
+- name: Create a larger cluster
+ sensu.sensu_go.cluster:
+ name: large-cluster
+ api_urls:
+ - https://sensu.alpha.example.com:8080
+ - https://sensu.beta.example.com:8080
+ - https://sensu.gamma.example.com:8080
+
+- name: Delete a cluster
+ sensu.sensu_go.cluster:
+ name: small-cluster
+ state: absent
+"""
+
+RETURN = """
+object:
+ description: Object representing Sensu cluster.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: alpha-cluster
+ api_urls:
+ - "http://10.10.0.1:8080"
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "federation/v1"
+
+
+def main():
+ required_if = [
+ ("state", "present", ["api_urls"]),
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "name", "state"),
+ api_urls=dict(type="list", elements="str"),
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, "clusters", module.params["name"],
+ )
+
+ payload = dict(
+ type="Cluster",
+ api_version=API_VERSION,
+ metadata=dict(name=module.params["name"]),
+ spec=arguments.get_spec_payload(module.params, "api_urls"),
+ )
+ try:
+ changed, cluster = utils.sync_v1(
+ module.params["state"], client, path, payload, module.check_mode,
+ )
+ module.exit_json(changed=changed, object=cluster)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/cluster_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/cluster_info.py
new file mode 100644
index 00000000..0fb64c27
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/cluster_info.py
@@ -0,0 +1,101 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2021, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: cluster_info
+author:
+ - Tadej Borovsak (@tadeboro)
+short_description: List available Sensu Go clusters
+description:
+ - Retrieve information about Sensu Go clusters.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/deploy-sensu/cluster-sensu/).
+version_added: 1.9.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+seealso:
+ - module: sensu.sensu_go.cluster
+"""
+
+EXAMPLES = """
+- name: List all Sensu Go clusters
+ sensu.sensu_go.etcd_replicator_info:
+ register: result
+
+- name: Retrieve the selected Sensu Go cluster
+ sensu.sensu_go.etcd_replicator_info:
+ name: my-cluster
+ register: result
+
+- name: Do something with result
+ ansible.builtin.debug:
+ msg: "{{ result.objects.0.api_urls }}"
+"""
+
+RETURN = """
+objects:
+ description: List of Sensu Go etcd clusters.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: alpha-cluster
+ api_urls:
+ - "http://10.10.0.1:8080"
+ - metadata:
+ name: beta-cluster
+ api_urls:
+ - "https://10.20.0.1:8080"
+ - "https://10.20.0.2:8080"
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "federation/v1"
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, "clusters", module.params["name"],
+ )
+
+ try:
+ clusters = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ # We simulate the behavior of v2 API here and only return the spec.
+ module.exit_json(changed=False, objects=[
+ utils.convert_v1_to_v2_response(s) for s in clusters
+ ])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role.py b/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role.py
new file mode 100644
index 00000000..20aecb54
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role.py
@@ -0,0 +1,164 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: cluster_role
+author:
+ - Paul Arthur (@flowerysong)
+ - Manca Bizjak (@mancabizjak)
+ - Aljaz Kosir (@aljazkosir)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu cluster roles
+description:
+ - Create, update or delete Sensu role.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#roles-and-cluster-roles).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.state
+seealso:
+ - module: sensu.sensu_go.cluster_role_info
+ - module: sensu.sensu_go.cluster_role_binding
+ - module: sensu.sensu_go.role
+ - module: sensu.sensu_go.role_binding
+options:
+ rules:
+ description:
+ - Rules that the cluster role applies.
+ - Must be non-empty if I(state) is C(present).
+ type: list
+ elements: dict
+ suboptions:
+ verbs:
+ description:
+ - Permissions to be applied by the rule.
+ type: list
+ elements: str
+ required: yes
+ choices: [get, list, create, update, delete]
+ resources:
+ description:
+ - Types of resources the rule has permission to access.
+ type: list
+ elements: str
+ required: yes
+ resource_names:
+ description:
+ - Names of specific resources the rule has permission to access.
+ - Note that for the C(create) verb, this argument will not be
+ taken into account when enforcing RBAC, even if it is provided.
+ type: list
+ elements: str
+'''
+
+EXAMPLES = '''
+- name: Create a cluster role
+ sensu.sensu_go.cluster_role:
+ name: readonly
+ rules:
+ - verbs:
+ - get
+ - list
+ resources:
+ - checks
+ - entities
+
+- name: Delete a cluster role
+ sensu.sensu_go.cluster_role:
+ name: readonly
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu cluster role.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: cluster-role
+ rules:
+ - resource_names:
+ - sample-name
+ resources:
+ - assets
+ - checks
+ verbs:
+ - get
+ - list
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils, role_utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "name", "state"),
+ rules=dict(
+ type="list",
+ elements="dict",
+ options=dict(
+ verbs=dict(
+ required=True,
+ type="list",
+ elements="str",
+ choices=["get", "list", "create", "update", "delete"],
+ ),
+ resources=dict(
+ required=True,
+ type="list",
+ elements="str",
+ ),
+ resource_names=dict(
+ type="list",
+ elements="str",
+ ),
+ )
+ )
+ )
+ )
+
+ msg = role_utils.validate_module_params(module.params)
+ if msg:
+ module.fail_json(msg=msg)
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ None, "clusterroles", module.params["name"],
+ )
+ payload = arguments.get_mutation_payload(
+ module.params, "rules"
+ )
+
+ try:
+ changed, cluster_role = utils.sync(
+ module.params['state'], client, path,
+ payload, module.check_mode, role_utils.do_roles_differ
+ )
+ module.exit_json(changed=changed, object=cluster_role)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_binding.py b/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_binding.py
new file mode 100644
index 00000000..de60d025
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_binding.py
@@ -0,0 +1,145 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: cluster_role_binding
+author:
+ - Paul Arthur (@flowerysong)
+ - Manca Bizjak (@mancabizjak)
+ - Aljaz Kosir (@aljazkosir)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu cluster role bindings
+description:
+ - Create, update or delete Sensu cluster role binding.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#role-bindings-and-cluster-role-bindings).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.state
+options:
+ cluster_role:
+ description:
+ - Name of the cluster role.
+ - Required if I(state) is C(present).
+ type: str
+ users:
+ description:
+ - List of users to bind to the cluster role.
+ - Note that at least one of I(users) and I(groups) must be
+ specified when creating a cluster role binding.
+ type: list
+ elements: str
+ groups:
+ description:
+ - List of groups to bind to the cluster role.
+ - Note that at least one of I(users) and I(groups) must be
+ specified when creating a cluster role binding.
+ type: list
+ elements: str
+seealso:
+ - module: sensu.sensu_go.cluster_role_binding_info
+ - module: sensu.sensu_go.cluster_role
+ - module: sensu.sensu_go.role_binding
+'''
+
+EXAMPLES = '''
+- name: Create a cluster role binding
+ sensu.sensu_go.cluster_role_binding:
+ name: all-cluster-admins
+ cluster_role: cluster-admin
+ groups:
+ - cluster-admins
+ users:
+ - alice
+
+- name: Delete a cluster role binding
+ sensu.sensu_go.cluster_role_binding:
+ name: all-cluster-admins
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu cluster role binding.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: cluster-admin
+ role_ref:
+ name: cluster-admin
+ type: ClusterRole
+ subjects:
+ - name: cluster-admins
+ type: Group
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils, role_utils
+
+
+def build_api_payload(params):
+ payload = arguments.get_mutation_payload(params)
+ payload["subjects"] = role_utils.build_subjects(params["groups"], params["users"])
+ payload["role_ref"] = role_utils.type_name_dict("ClusterRole", params["cluster_role"])
+
+ return payload
+
+
+def main():
+ required_if = [
+ ("state", "present", ["cluster_role"])
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "name", "state"),
+ cluster_role=dict(),
+ users=dict(
+ type="list", elements="str",
+ ),
+ groups=dict(
+ type="list", elements="str",
+ ),
+ )
+ )
+
+ msg = role_utils.validate_binding_module_params(module.params)
+ if msg:
+ module.fail_json(msg=msg)
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ None, "clusterrolebindings", module.params["name"],
+ )
+ payload = build_api_payload(module.params)
+
+ try:
+ changed, cluster_role_binding = utils.sync(
+ module.params["state"], client, path, payload, module.check_mode, role_utils.do_role_bindings_differ
+ )
+ module.exit_json(changed=changed, object=cluster_role_binding)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_binding_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_binding_info.py
new file mode 100644
index 00000000..8d46fdc9
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_binding_info.py
@@ -0,0 +1,97 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: cluster_role_binding_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Manca Bizjak (@mancabizjak)
+ - Aljaz Kosir (@aljazkosir)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu cluster role bindings
+description:
+ - Retrieve information about Sensu cluster role bindings.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#role-bindings-and-cluster-role-bindings).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+seealso:
+ - module: sensu.sensu_go.cluster_role_binding
+'''
+
+EXAMPLES = '''
+- name: List all Sensu cluster role bindings
+ sensu.sensu_go.cluster_role_binding_info:
+ register: result
+
+- name: Retrieve a specific Sensu cluster role binding
+ sensu.sensu_go.cluster_role_binding_info:
+ name: my-binding
+ register: result
+'''
+
+RETURN = '''
+objects:
+ description: List of Sensu cluster role bindings.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: cluster-admin
+ role_ref:
+ name: cluster-admin
+ type: ClusterRole
+ subjects:
+ - name: cluster-admins
+ type: Group
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth"),
+ name=dict()
+ )
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ None, "clusterrolebindings", module.params["name"],
+ )
+
+ try:
+ cluster_role_bindings = utils.prepare_result_list(
+ utils.get(client, path)
+ )
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=cluster_role_bindings)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_info.py
new file mode 100644
index 00000000..e2374dff
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/cluster_role_info.py
@@ -0,0 +1,98 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: cluster_role_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Manca Bizjak (@mancabizjak)
+ - Aljaz Kosir (@aljazkosir)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu cluster roles
+description:
+ - Retrieve information about Sensu roles.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#roles-and-cluster-roles).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+seealso:
+ - module: sensu.sensu_go.cluster_role
+'''
+
+EXAMPLES = '''
+- name: List all Sensu cluster roles
+ sensu.sensu_go.cluster_role_info:
+ register: result
+
+- name: Retrieve Sensu cluster role by name
+ sensu.sensu_go.cluster_role_info:
+ name: my-custer-role
+ register: result
+'''
+
+RETURN = '''
+roles:
+ description: List of Sensu cluster roles.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: cluster-role
+ rules:
+ - resource_names:
+ - sample-name
+ resources:
+ - assets
+ - checks
+ verbs:
+ - get
+ - list
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth"),
+ name=dict()
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ None, "clusterroles", module.params["name"],
+ )
+
+ try:
+ cluster_roles = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=cluster_roles)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/datastore.py b/ansible_collections/sensu/sensu_go/plugins/modules/datastore.py
new file mode 100644
index 00000000..706f3d1d
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/datastore.py
@@ -0,0 +1,170 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: datastore
+author:
+ - Manca Bizjak (@mancabizjak)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu external datastore providers
+description:
+ - Add or remove external datastore provider.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/datastore/).
+version_added: 1.1.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.state
+seealso:
+ - module: sensu.sensu_go.datastore_info
+options:
+ dsn:
+ description:
+ - Attribute that specifies the data source names as a URL or
+ PostgreSQL connection string. See the PostgreSQL docs for more
+ information about connection strings.
+ type: str
+ pool_size:
+ description:
+ - The maximum number of connections to hold in the PostgreSQL connection
+ pool.
+ type: int
+notes:
+ - Currently, only one external datastore can be active at a time. The module
+ will fail to perform its operation if this would break that invariant.
+'''
+
+EXAMPLES = '''
+- name: Add external datastore
+ sensu.sensu_go.datastore:
+ name: my-postgres
+ dsn: postgresql://user:secret@host:port/dbname
+
+- name: Remove external datastore
+ sensu.sensu_go.datastore:
+ name: my-postgres
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing external datastore provider.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: my-postgres
+ batch_buffer: 0
+ batch_size: 1
+ batch_workers: 0
+ dsn: "postgresql://user:secret@host:port/dbname"
+ max_conn_lifetime: 5m
+ max_idle_conns: 2
+ pool_size: 20
+ strict: true
+ enable_round_robin: true
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "store/v1"
+
+
+def _get(client, path):
+ return utils.convert_v1_to_v2_response(utils.get(client, path))
+
+
+def sync(state, client, list_path, resource_path, payload, check_mode):
+ datastore = _get(client, resource_path)
+
+ # When we are deleting stores, we do not care if there is more than one
+ # datastore present. We just make sure the currently manipulated store is
+ # gone. This makes our module useful in "let us clean up the mess"
+ # scenarios.
+ if state == "absent" and datastore is None:
+ return False, None
+
+ if state == "absent":
+ if not check_mode:
+ utils.delete(client, resource_path)
+ return True, None
+
+ # If the store exists, update it and ignore the fact that there might be
+ # more than one present.
+ if datastore:
+ if utils.do_differ(datastore, payload["spec"]):
+ if check_mode:
+ return True, payload["spec"]
+ utils.put(client, resource_path, payload)
+ return True, _get(client, resource_path)
+ return False, datastore
+
+ # When adding a new datastore, we first make sure there is no other
+ # datastore present because we do not want to be the ones who brought
+ # backends into an inconsistent state.
+ if utils.get(client, list_path):
+ raise errors.Error("Some other external datastore is already active.")
+
+ if check_mode:
+ return True, payload["spec"]
+ utils.put(client, resource_path, payload)
+ return True, _get(client, resource_path)
+
+
+def main():
+ required_if = [
+ ("state", "present", ["dsn"])
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "name", "state"),
+ dsn=dict(),
+ pool_size=dict(
+ type="int",
+ )
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ list_path = utils.build_url_path(API_GROUP, API_VERSION, None, "provider")
+ resource_path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, "provider", module.params["name"],
+ )
+ payload = dict(
+ type="PostgresConfig",
+ api_version=API_VERSION,
+ metadata=dict(name=module.params["name"]),
+ spec=arguments.get_spec_payload(module.params, "dsn", "pool_size"),
+ )
+
+ try:
+ changed, datastore = sync(
+ module.params["state"], client, list_path, resource_path, payload,
+ module.check_mode,
+ )
+ module.exit_json(changed=changed, object=datastore)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/datastore_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/datastore_info.py
new file mode 100644
index 00000000..b31c6481
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/datastore_info.py
@@ -0,0 +1,104 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: datastore_info
+author:
+ - Manca Bizjak (@mancabizjak)
+ - Tadej Borovsak (@tadeboro)
+short_description: List external Sensu datastore providers
+description:
+ - Retrieve information about external Sensu datastores.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/datastore/).
+version_added: 1.1.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+seealso:
+ - module: sensu.sensu_go.datastore
+"""
+
+EXAMPLES = """
+- name: List all external Sensu datastores
+ sensu.sensu_go.datastore_info:
+ register: result
+
+- name: Retrieve the selected external Sensu datastore
+ sensu.sensu_go.datastore_info:
+ name: my-datastore
+ register: result
+
+- name: Do something with result
+ ansible.builtin.debug:
+ msg: "{{ result.objects.0.dsn }}"
+"""
+
+RETURN = """
+objects:
+ description: List of external Sensu datastore providers.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: my-postgres
+ batch_buffer: 0
+ batch_size: 1
+ batch_workers: 0
+ dsn: "postgresql://user:secret@host:port/dbname"
+ max_conn_lifetime: 5m
+ max_idle_conns: 2
+ pool_size: 20
+ strict: true
+ enable_round_robin: true
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "store/v1"
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, "provider", module.params["name"],
+ )
+
+ try:
+ stores = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ # We simulate the behavior of v2 API here and only return the spec.
+ module.exit_json(changed=False, objects=[
+ utils.convert_v1_to_v2_response(s) for s in stores
+ ])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/entity.py b/ansible_collections/sensu/sensu_go/plugins/modules/entity.py
new file mode 100644
index 00000000..e8d1562d
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/entity.py
@@ -0,0 +1,261 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: entity
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu entities
+description:
+ - Create, update or delete Sensu entity.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/entities/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+ - sensu.sensu_go.labels
+ - sensu.sensu_go.annotations
+seealso:
+ - module: sensu.sensu_go.entity_info
+options:
+ entity_class:
+ description:
+ - Entity class. Standard classes are C(proxy) and C(agent), but you can
+ use whatever you want.
+ - Required if I(state) is C(present).
+ type: str
+ subscriptions:
+ description:
+ - List of subscriptions for the entity.
+ type: list
+ elements: str
+ system:
+ description:
+ - System information about the entity, such as operating system and platform. See
+ U(https://docs.sensu.io/sensu-go/5.13/reference/entities/#system-attributes) for more information.
+ type: dict
+ last_seen:
+ description:
+ - Timestamp the entity was last seen, in seconds since the Unix epoch.
+ type: int
+ deregister:
+ description:
+ - If the entity should be removed when it stops sending keepalive messages.
+ type: bool
+ deregistration_handler:
+ description:
+ - The name of the handler to be called when an entity is deregistered.
+ type: str
+ redact:
+ description:
+ - List of items to redact from log messages. If a value is provided,
+ it overwrites the default list of items to be redacted.
+ type: list
+ elements: str
+ user:
+ description:
+ - Sensu RBAC username used by the entity. Agent entities require get,
+ list, create, update, and delete permissions for events across all namespaces.
+ type: str
+'''
+
+EXAMPLES = '''
+- name: Create an entity
+ sensu.sensu_go.entity:
+ auth:
+ url: http://localhost:8080
+ name: entity
+ entity_class: proxy
+ subscriptions:
+ - web
+ - prod
+ system:
+ hostname: playbook-entity
+ os: linux
+ platform: ubutntu
+ network:
+ interfaces:
+ - name: lo
+ addresses:
+ - 127.0.0.1/8
+ - ::1/128
+ - name: eth0
+ mac: 52:54:00:20:1b:3c
+ addresses:
+ - 93.184.216.34/24
+ last_seen: 1522798317
+ deregister: yes
+ deregistration_handler: email-handler
+ redact:
+ - password
+ - pass
+ - api_key
+ user: agent
+
+- name: Delete an entity
+ sensu.sensu_go.entity:
+ name: entity
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu entity.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ annotations: null
+ labels: null
+ name: webserver01
+ namespace: default
+ deregister: false
+ deregistration: {}
+ entity_class: agent
+ last_seen: 1542667231
+ redact:
+ - password
+ - private_key
+ - secret
+ subscriptions:
+ - entity:webserver01
+ system:
+ arch: amd64
+ libc_type: glibc
+ vm_system: kvm
+ vm_role: host
+ cloud_provider: null
+ network:
+ interfaces:
+ - addresses:
+ - 127.0.0.1/8
+ - ::1/128
+ name: lo
+ - addresses:
+ - 172.28.128.3/24
+ - fe80::a00:27ff:febc:be60/64
+ mac: 08:00:27:bc:be:60
+ name: enp0s8
+ os: linux
+ platform: centos
+ platform_family: rhel
+ platform_version: 7.4.1708
+ sensu_agent_version: 1.0.0
+ user: agent
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def do_differ(current, desired):
+ system = desired.get('system')
+ if system and utils.do_differ(current.get('system'), system):
+ return True
+
+ subs = desired.get('subscriptions')
+ if subs is not None and set(subs) != set(current.get('subscriptions', [])):
+ return True
+
+ return utils.do_differ(current, desired, 'system', 'subscriptions')
+
+
+def main():
+ required_if = [
+ ('state', 'present', ['entity_class'])
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth", "name", "state", "labels", "annotations", "namespace",
+ ),
+ entity_class=dict(),
+ subscriptions=dict(
+ type='list', elements='str',
+ ),
+ system=dict(
+ type='dict'
+ ),
+ last_seen=dict(
+ type='int'
+ ),
+ deregister=dict(
+ type='bool'
+ ),
+ deregistration_handler=dict(),
+ redact=dict(
+ type='list', elements='str',
+ ),
+ user=dict()
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ module.params['namespace'], 'entities', module.params['name'],
+ )
+ payload = arguments.get_mutation_payload(
+ module.params, 'entity_class', 'subscriptions', 'system', 'last_seen', 'deregister',
+ 'redact', 'user'
+ )
+ if module.params['deregistration_handler']:
+ payload['deregistration'] = dict(handler=module.params['deregistration_handler'])
+
+ # As per conversation with @echlebek, the only two supported entity
+ # classes are agent and proxy. All other classes can lead to undefined
+ # behavior and should not be used.
+ eclass = payload.get('entity_class')
+ if eclass and eclass not in ('agent', 'proxy'):
+ deprecation_msg = (
+ 'The `entity_class` parameter should be set to either `agent` or '
+ '`proxy`. All other values can result in undefined behavior of '
+ 'the Sensu Go backend.'
+ )
+ utils.deprecate(module, deprecation_msg, '2.0.0')
+
+ # Agent entities always have entity:{entity_name} subscription enabled
+ # even if we pass an empty subscriptions. In order to prevent falsely
+ # reporting changed: true, we always add this subscription to the agent
+ # entities.
+ if eclass == 'agent':
+ entity_sub = 'entity:' + module.params['name']
+ subs = payload.get('subscriptions', [])
+ if entity_sub not in subs:
+ # Copy subs in order to avoid mutating module params
+ payload['subscriptions'] = subs + [entity_sub]
+
+ try:
+ changed, entity = utils.sync(
+ module.params['state'], client, path, payload, module.check_mode,
+ do_differ,
+ )
+ module.exit_json(changed=changed, object=entity)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/entity_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/entity_info.py
new file mode 100644
index 00000000..511dd237
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/entity_info.py
@@ -0,0 +1,125 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: entity_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu entities
+description:
+ - Retrieve information about Sensu entities.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/entities/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.entity
+'''
+
+EXAMPLES = '''
+- name: List all Sensu entities
+ sensu.sensu_go.entity_info:
+ register: result
+
+- name: Retrieve a specific Sensu entity
+ sensu.sensu_go.entity_info:
+ name: my-entity
+ register: result
+'''
+
+RETURN = '''
+objects:
+ description: List of Sensu entities.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ annotations: null
+ labels: null
+ name: webserver01
+ namespace: default
+ deregister: false
+ deregistration: {}
+ entity_class: agent
+ last_seen: 1542667231
+ redact:
+ - password
+ - private_key
+ - secret
+ subscriptions:
+ - entity:webserver01
+ system:
+ arch: amd64
+ libc_type: glibc
+ vm_system: kvm
+ vm_role: host
+ cloud_provider: null
+ network:
+ interfaces:
+ - addresses:
+ - 127.0.0.1/8
+ - ::1/128
+ name: lo
+ - addresses:
+ - 172.28.128.3/24
+ - fe80::a00:27ff:febc:be60/64
+ mac: 08:00:27:bc:be:60
+ name: enp0s8
+ os: linux
+ platform: centos
+ platform_family: rhel
+ platform_version: 7.4.1708
+ sensu_agent_version: 1.0.0
+ user: agent
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "entities", module.params["name"],
+ )
+
+ try:
+ entities = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=entities)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/etcd_replicator.py b/ansible_collections/sensu/sensu_go/plugins/modules/etcd_replicator.py
new file mode 100644
index 00000000..143aca8f
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/etcd_replicator.py
@@ -0,0 +1,218 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2021, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: etcd_replicator
+author:
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu Go etcd replicators
+description:
+ - Create, update or delete Sensu etcd replicator.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/deploy-sensu/etcdreplicators/).
+version_added: 1.9.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.state
+seealso:
+ - module: sensu.sensu_go.etcd_replicator_info
+options:
+ ca_cert:
+ description:
+ - Path to an the PEM-format CA certificate to use for TLS client authentication.
+ - Required if I(insecure) is C(false).
+ type: str
+ cert:
+ description:
+ - Path to the PEM-format certificate to use for TLS client authentication. This
+ certificate is required for secure client communication.
+ - Required if I(insecure) is C(false).
+ type: str
+ key:
+ description:
+ - Path to the PEM-format key file associated with the cert to use for TLS client
+ authentication. This key and its corresponding certificate are required for
+ secure client communication.
+ - Required if I(insecure) is C(false).
+ type: str
+ insecure:
+ description:
+ - Disable transport security.
+ - Only set to C(true) in sandbox and experimental environments.
+ type: bool
+ default: false
+ url:
+ description:
+ - Destination cluster URLs.
+ - Required if I(state) is C(present).
+ type: list
+ elements: str
+ api_version:
+ description:
+ - Sensu API version of the resource to replicate.
+ type: str
+ resource:
+ description:
+ - Name of the resource to replicate.
+ - List of all resources is available at
+ U(https://docs.sensu.io/sensu-go/latest/operations/control-access/rbac/#resources).
+ - Required if I(state) is C(present).
+ type: str
+ namespace:
+ description:
+ - Namespace to constrain replication to.
+ - If you do not include namespace, all namespaces for a given resource are
+ replicated.
+ type: str
+ replication_interval:
+ description:
+ - Interval at which the resource will be replicated. In seconds.
+ type: int
+"""
+
+EXAMPLES = """
+- name: Create a minimal replicator
+ sensu.sensu_go.etcd_replicator:
+ name: cluster_role_replicator
+ ca_cert: /etc/sensu/certs/ca.pem
+ cert: /etc/sensu/certs/cert.pem
+ key: /etc/sensu/certs/key.pem
+ url: https://sensu.alpha.example.com:2379
+ resource: ClusterRole
+
+- name: Create an insecure minimal replicator
+ sensu.sensu_go.etcd_replicator:
+ name: role_replicator
+ insecure: true
+ url:
+ - https://sensu.beta.example.com:2379
+ - https://sensu.gamma.example.com:2379
+ resource: Role
+
+- name: Create a replicator with all parameters set
+ sensu.sensu_go.etcd_replicator:
+ name: role_binding_replicator
+ ca_cert: /etc/sensu/certs/ca.pem
+ cert: /etc/sensu/certs/cert.pem
+ key: /etc/sensu/certs/key.pem
+ insecure: false
+ url: https://127.0.0.1:2379
+ api_version: core/v2
+ resource: RoleBinding
+ namespace: default
+ replication_interval_seconds: 30
+
+- name: Delete a replicator
+ sensu.sensu_go.etcd_replicator:
+ name: my_replicator
+ state: absent
+"""
+
+RETURN = """
+object:
+ description: Object representing Sensu etcd replicator.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ created_by: admin
+ name: cluster-role-replicator
+ api_version: core/v2
+ ca_cert: /etc/sensu/certs/ca.pem
+ cert: /etc/sensu/certs/cert.pem
+ insecure: false
+ key: /etc/sensu/certs/key.pem
+ namespace: ""
+ replication_interval_seconds: 30
+ resource: ClusterRole
+ url: https://sensu.alpha.example.com:2379
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "federation/v1"
+
+
+def main():
+ required_if = [
+ ("state", "present", ["url", "resource"]),
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "name", "state"),
+ ca_cert=dict(type="str"),
+ cert=dict(type="str"),
+ key=dict(type="str", no_log=False),
+ insecure=dict(type="bool", default=False),
+ url=dict(type="list", elements="str"),
+ api_version=dict(type="str"),
+ resource=dict(type="str"),
+ namespace=dict(type="str"),
+ replication_interval=dict(type="int"),
+ ),
+ )
+
+ # This complex condition cannot be expressed using built-in checks.
+ if module.params["state"] == "present" and module.params["insecure"] is False:
+ missing = []
+ for key in ("ca_cert", "cert", "key"):
+ if not module.params[key]:
+ missing.append(key)
+ if missing:
+ msg = "insecure is False but all of the following are missing: {0}".format(
+ ", ".join(missing)
+ )
+ module.fail_json(msg=msg)
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, "etcd-replicators", module.params["name"],
+ )
+
+ spec = arguments.get_spec_payload(
+ module.params, "ca_cert", "cert", "key", "insecure", "api_version",
+ "resource", "namespace",
+ )
+ # We renamed the replication interval a bit.
+ if module.params["replication_interval"] is not None:
+ spec["replication_interval_seconds"] = module.params["replication_interval"]
+ # We accept a list of urls that we need to convert here
+ if module.params["url"]:
+ spec["url"] = ",".join(module.params["url"])
+
+ payload = dict(
+ type="EtcdReplicator",
+ api_version=API_VERSION,
+ metadata=dict(name=module.params["name"]),
+ spec=spec,
+ )
+ try:
+ changed, replicator = utils.sync_v1(
+ module.params["state"], client, path, payload, module.check_mode,
+ )
+ module.exit_json(changed=changed, object=replicator)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/etcd_replicator_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/etcd_replicator_info.py
new file mode 100644
index 00000000..cf58d7c8
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/etcd_replicator_info.py
@@ -0,0 +1,104 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2020, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: etcd_replicator_info
+author:
+ - Tadej Borovsak (@tadeboro)
+short_description: List available Sensu Go etcd replicators
+description:
+ - Retrieve information about Sensu Go etcd replicators.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/deploy-sensu/etcdreplicators/).
+version_added: 1.9.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+seealso:
+ - module: sensu.sensu_go.etcd_replicator
+"""
+
+EXAMPLES = """
+- name: List all Sensu Go etcd replicators
+ sensu.sensu_go.etcd_replicator_info:
+ register: result
+
+- name: Retrieve the selected Sensu Go etcd replicator
+ sensu.sensu_go.etcd_replicator_info:
+ name: role_replicator
+ register: result
+
+- name: Do something with result
+ ansible.builtin.debug:
+ msg: "{{ result.objects.0.resource }}"
+"""
+
+RETURN = """
+objects:
+ description: List of Sensu Go etcd replicators.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ created_by: admin
+ name: cluster-role-replicator
+ api_version: core/v2
+ ca_cert: /etc/sensu/certs/ca.pem
+ cert: /etc/sensu/certs/cert.pem
+ insecure: false
+ key: /etc/sensu/certs/key.pem
+ namespace: ""
+ replication_interval_seconds: 30
+ resource: ClusterRole
+ url: https://sensu.alpha.example.com:2379
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "federation/v1"
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, "etcd-replicators", module.params["name"],
+ )
+
+ try:
+ replicators = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ # We simulate the behavior of v2 API here and only return the spec.
+ module.exit_json(changed=False, objects=[
+ utils.convert_v1_to_v2_response(s) for s in replicators
+ ])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/event.py b/ansible_collections/sensu/sensu_go/plugins/modules/event.py
new file mode 100644
index 00000000..ae2ae333
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/event.py
@@ -0,0 +1,335 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: event
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu events
+description:
+ - Send a synthetic event to Sensu.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/events/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.event_info
+notes:
+ - Metric events bypass the store and are sent off to the event pipeline and corresponding event
+ handlers. Read more about this at
+ U(https://docs.sensu.io/sensu-go/latest/reference/events/#metric-only-events).
+options:
+ timestamp:
+ description:
+ - UNIX time at which the event occurred.
+ type: int
+ entity:
+ description:
+ - Name of the entity associated with this event. It must exist before event creation.
+ type: str
+ required: true
+ check:
+ description:
+ - Name of the check associated with this event. It must exist before event creation.
+ type: str
+ required: true
+ check_attributes:
+ type: dict
+ description:
+ - Additional check parameters. Find out more at
+ U(https://docs.sensu.io/sensu-go/latest/reference/events/#check-attributes).
+ suboptions:
+ duration:
+ description:
+ - Command execution time in seconds.
+ type: float
+ executed:
+ description:
+ - Time that the check request was executed.
+ type: int
+ history:
+ description:
+ - Check status history for the last 21 check executions.
+ type: list
+ elements: dict
+ issued:
+ description:
+ - Time that the check request was issued in seconds since the Unix epoch.
+ type: int
+ last_ok:
+ description:
+ - The last time that the check returned an OK status (0) in seconds since the Unix epoch.
+ type: int
+ output:
+ description:
+ - The output from the execution of the check command.
+ type: str
+ state:
+ description:
+ - The state of the check.
+ choices: [ "passing", "failing", "flapping" ]
+ type: str
+ status:
+ description:
+ - Exit status code produced by the check.
+ choices: [ "ok", "warning", "critical", "unknown" ]
+ type: str
+ total_state_change:
+ description:
+ - The total state change percentage for the check's history.
+ type: int
+ metric_attributes:
+ type: dict
+ description:
+ - Metric attributes. Find out more at
+ U(https://docs.sensu.io/sensu-go/latest/reference/events/#metric-attributes).
+ suboptions:
+ handlers:
+ description:
+ - An array of Sensu handlers to use for events created by the check.
+ Each array item must be a string.
+ type: list
+ elements: str
+ points:
+ description:
+ - Metric data points including a name, timestamp, value, and tags.
+ type: list
+ elements: dict
+'''
+
+EXAMPLES = '''
+- name: Create an event
+ sensu.sensu_go.event:
+ auth:
+ url: http://localhost:8080
+ entity: awesome_entity
+ check: awesome_check
+ check_attributes:
+ duration: 1.945
+ executed: 1522100915
+ history:
+ - executed: 1552505193
+ status: 1
+ issued: 1552506034
+ last_ok: 1552506033
+ output: '10'
+ state: 'passing'
+ status: 'ok'
+ total_state_change: 0
+ metric_attributes:
+ handlers:
+ - handler1
+ - handler2
+ points:
+ - name: "sensu-go-sandbox.curl_timings.time_total"
+ tags:
+ - name: "response_time_in_ms"
+ value: 101
+ timestamp: 1552506033
+ value: 0.005
+ - name: "sensu-go-sandbox.curl_timings.time_namelookup"
+ tags:
+ - name: "namelookup_time_in_ms"
+ value: 57
+ timestamp: 1552506033
+ value: 0.004
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu event (deprecated).
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ namespace: default
+ check:
+ check_hooks: null
+ command: check-cpu.sh -w 75 -c 90
+ duration: 1.07055808
+ env_vars: null
+ executed: 1552594757
+ handlers: []
+ high_flap_threshold: 0
+ history:
+ - executed: 1552594757
+ status: 0
+ interval: 60
+ metadata:
+ name: check-cpu
+ namespace: default
+ occurrences: 1
+ occurrences_watermark: 1
+ output: CPU OK - Usage:3.96
+ subscriptions:
+ - linux
+ timeout: 0
+ total_state_change: 0
+ ttl: 0
+ entity:
+ deregister: false
+ deregistration: {}
+ entity_class: agent
+ last_seen: 1552594641
+ metadata:
+ name: sensu-centos
+ namespace: default
+ timestamp: 1552594758
+ id: 3a5948f3-6ffd-4ea2-a41e-334f4a72ca2f
+ sequence: 1
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+STATUS_MAP = {
+ 'ok': 0,
+ 'warning': 1,
+ 'critical': 2,
+ 'unknown': 3,
+}
+
+
+def get_check(client, namespace, check):
+ check_path = utils.build_core_v2_path(namespace, 'checks', check)
+ resp = client.get(check_path)
+ if resp.status != 200:
+ raise errors.SyncError("Check with name '{0}' does not exist on remote.".format(check))
+ return resp.json
+
+
+def get_entity(client, namespace, entity):
+ entity_path = utils.build_core_v2_path(namespace, 'entities', entity)
+ resp = client.get(entity_path)
+ if resp.status != 200:
+ raise errors.SyncError("Entity with name '{0}' does not exist on remote.".format(entity))
+ return resp.json
+
+
+def _update_payload_with_metric_attributes(payload, metric_attributes):
+ if not metric_attributes:
+ return
+
+ payload['metrics'] = arguments.get_spec_payload(metric_attributes, *metric_attributes.keys())
+
+
+def _update_payload_with_check_attributes(payload, check_attributes):
+ if not check_attributes:
+ return
+
+ if check_attributes['status']:
+ check_attributes['status'] = STATUS_MAP[check_attributes['status']]
+
+ filtered_attributes = arguments.get_spec_payload(check_attributes, *check_attributes.keys())
+ payload['check'].update(filtered_attributes)
+
+
+def _build_api_payload(client, params):
+ payload = arguments.get_spec_payload(params, 'timestamp')
+ payload['metadata'] = dict(
+ namespace=params['namespace']
+ )
+ payload['entity'] = get_entity(client, params['namespace'], params['entity'])
+ payload['check'] = get_check(client, params['namespace'], params['check'])
+
+ _update_payload_with_check_attributes(payload, params['check_attributes'])
+ _update_payload_with_metric_attributes(payload, params['metric_attributes'])
+ return payload
+
+
+def send_event(client, path, payload, check_mode):
+ if not check_mode:
+ utils.put(client, path, payload)
+ return True, payload
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ timestamp=dict(type='int'),
+ entity=dict(required=True),
+ check=dict(required=True),
+ check_attributes=dict(
+ type='dict',
+ options=dict(
+ duration=dict(
+ type='float'
+ ),
+ executed=dict(
+ type='int'
+ ),
+ history=dict(
+ type='list', elements='dict',
+ ),
+ issued=dict(
+ type='int'
+ ),
+ last_ok=dict(
+ type='int'
+ ),
+ output=dict(),
+ state=dict(
+ choices=['passing', 'failing', 'flapping']
+ ),
+ status=dict(
+ choices=['ok', 'warning', 'critical', 'unknown']
+ ),
+ total_state_change=dict(
+ type='int'
+ )
+ )
+ ),
+ metric_attributes=dict(
+ type='dict',
+ options=dict(
+ handlers=dict(
+ type='list',
+ elements='str'
+ ),
+ points=dict(
+ type='list',
+ elements='dict'
+ )
+ )
+ )
+ )
+ )
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ module.params['namespace'], 'events', module.params['entity'],
+ module.params['check'],
+ )
+
+ try:
+ payload = _build_api_payload(client, module.params)
+ changed, event = send_event(client, path, payload, module.check_mode)
+ module.exit_json(changed=changed, object=event)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/event_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/event_info.py
new file mode 100644
index 00000000..90a4d84f
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/event_info.py
@@ -0,0 +1,142 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: event_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu events
+description:
+ - Retrieve recent events that Sensu processed.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/events/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.event
+options:
+ check:
+ description:
+ - Limit results to a specific check.
+ - I(entity) must also be specified if this parameter is used.
+ type: str
+ entity:
+ description:
+ - Limit results to a specific entity.
+ type: str
+'''
+
+EXAMPLES = '''
+- name: List Sensu events
+ sensu.sensu_go.event_info:
+ register: result
+
+- name: List Sensu events for api.example.com
+ sensu.sensu_go.event_info:
+ entity: api.example.com
+ register: result
+
+- name: Filter events by check and entity
+ sensu.sensu_go.event_info:
+ entity: api.example.com
+ check: check-cpu
+ register: result
+'''
+
+RETURN = '''
+objects:
+ description: List of Sensu events.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ namespace: default
+ check:
+ check_hooks: null
+ command: check-cpu.sh -w 75 -c 90
+ duration: 1.07055808
+ env_vars: null
+ executed: 1552594757
+ handlers: []
+ high_flap_threshold: 0
+ history:
+ - executed: 1552594757
+ status: 0
+ interval: 60
+ metadata:
+ name: check-cpu
+ namespace: default
+ occurrences: 1
+ occurrences_watermark: 1
+ output: CPU OK - Usage:3.96
+ subscriptions:
+ - linux
+ timeout: 0
+ total_state_change: 0
+ ttl: 0
+ entity:
+ deregister: false
+ deregistration: {}
+ entity_class: agent
+ last_seen: 1552594641
+ metadata:
+ name: sensu-centos
+ namespace: default
+ timestamp: 1552594758
+ id: 3a5948f3-6ffd-4ea2-a41e-334f4a72ca2f
+ sequence: 1
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ required_by = {'check': ['entity']}
+ module = AnsibleModule(
+ supports_check_mode=True,
+ required_by=required_by,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ check=dict(),
+ entity=dict(),
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ module.params['namespace'], 'events', module.params['entity'],
+ module.params['check'],
+ )
+
+ try:
+ events = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=events)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/filter.py b/ansible_collections/sensu/sensu_go/plugins/modules/filter.py
new file mode 100644
index 00000000..e8023b43
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/filter.py
@@ -0,0 +1,158 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: filter
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu filters
+description:
+ - Create, update or delete Sensu filter.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/filters/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+ - sensu.sensu_go.labels
+ - sensu.sensu_go.annotations
+seealso:
+ - module: sensu.sensu_go.filter_info
+options:
+ action:
+ description:
+ - Action to take with the event if the filter expressions match.
+ - Required if I(state) is C(present).
+ type: str
+ choices: [ 'allow', 'deny' ]
+ expressions:
+ description:
+ - Filter expressions to be compared with event data.
+ - Required if I(state) is C(present).
+ type: list
+ elements: str
+ runtime_assets:
+ description:
+ - Assets to be applied to the filter's execution context.
+ JavaScript files in the lib directory of the asset will be evaluated.
+ type: list
+ elements: str
+'''
+
+EXAMPLES = '''
+- name: Create a filter
+ sensu.sensu_go.filter:
+ name: filter
+ action: deny
+ expressions:
+ - event.check.interval == 10
+ - event.check.occurrences == 1
+ runtime_assets: awesomeness
+
+- name: Create a production filter
+ sensu.sensu_go.filter:
+ name: filter
+ action: allow
+ expressions:
+ - event.entity.labels['environment'] == 'production'
+
+- name: Create a filter with JS expression
+ sensu.sensu_go.filter:
+ name: filter
+ action: deny
+ expressions:
+ - "_.reduce(event.check.history, function(memo, h) { return (memo || h.status != 0); })"
+ runtime_assets:
+ - underscore
+
+- name: Handling repeated events
+ sensu.sensu_go.filter:
+ name: filter_interval_60_hourly
+ action: allow
+ expressions:
+ - event.check.interval == 60
+ - event.check.occurrences == 1 || event.check.occurrences % 60 == 0
+
+- name: Delete a filter
+ sensu.sensu_go.filter:
+ name: filter_interval_60_hourly
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu filter.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: filter_minimum
+ namespace: default
+ action: allow
+ expressions:
+ - event.check.occurrences == 1
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ required_if = [
+ ('state', 'present', ['action', 'expressions'])
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth", "name", "state", "labels", "annotations", "namespace",
+ ),
+ action=dict(choices=['allow', 'deny']),
+ expressions=dict(
+ type='list', elements='str',
+ ),
+ runtime_assets=dict(
+ type='list', elements='str',
+ ),
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ module.params['namespace'], 'filters', module.params['name'],
+ )
+ payload = arguments.get_mutation_payload(
+ module.params, 'action', 'expressions', 'runtime_assets'
+ )
+ try:
+ changed, sensu_filter = utils.sync(
+ module.params['state'], client, path, payload, module.check_mode,
+ )
+ module.exit_json(changed=changed, object=sensu_filter)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/filter_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/filter_info.py
new file mode 100644
index 00000000..bdad1fa5
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/filter_info.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: filter_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu info
+description:
+ - Retrieve information about Sensu filters.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/filters/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.filter
+'''
+
+EXAMPLES = '''
+- name: List all Sensu filters
+ sensu.sensu_go.filter_info:
+ register: result
+
+- name: Retrieve a specific Sensu filter
+ sensu.sensu_go.filter_info:
+ name: my-filter
+ register: result
+'''
+
+RETURN = '''
+objects:
+ description: List of Sensu filters.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: filter_minimum
+ namespace: default
+ action: allow
+ expressions:
+ - event.check.occurrences == 1
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "filters", module.params["name"],
+ )
+
+ try:
+ sensu_filters = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=sensu_filters)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/handler_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/handler_info.py
new file mode 100644
index 00000000..600de0a1
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/handler_info.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: handler_info
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu handlers
+description:
+ - Retrieve information about Sensu handlers.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/handlers/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.socket_handler
+ - module: sensu.sensu_go.pipe_handler
+ - module: sensu.sensu_go.handler_set
+'''
+
+EXAMPLES = '''
+- name: List all Sensu handlers
+ sensu.sensu_go.handler_info:
+ register: result
+
+- name: Retrieve info for a specific Sensu handler
+ sensu.sensu_go.handler_info:
+ name: my-handler
+ register: result
+'''
+
+RETURN = '''
+objects:
+ description: List of Sensu handlers.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: tcp_udp_handler_minimum
+ namespace: default
+ socket:
+ host: 10.0.1.99
+ port: 4444
+ type: tcp
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "handlers", module.params["name"],
+ )
+
+ try:
+ handlers = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=handlers)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/handler_set.py b/ansible_collections/sensu/sensu_go/plugins/modules/handler_set.py
new file mode 100644
index 00000000..aedc9856
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/handler_set.py
@@ -0,0 +1,119 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: handler_set
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu handler set
+description:
+ - Create, update or delete Sensu handler set.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/handlers/#handler-sets).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+ - sensu.sensu_go.labels
+ - sensu.sensu_go.annotations
+seealso:
+ - module: sensu.sensu_go.socket_handler
+ - module: sensu.sensu_go.pipe_handler
+ - module: sensu.sensu_go.handler_info
+options:
+ handlers:
+ description:
+ - List of Sensu event handlers (names) to use for events using the handler set.
+ - Required if I(state) is C(present).
+ type: list
+ elements: str
+'''
+
+EXAMPLES = '''
+- name: Create a handler set
+ sensu.sensu_go.handler_set:
+ name: notify_all_the_things
+ handlers:
+ - slack
+ - tcp_handler
+ - udp_handler
+
+- name: Delete a handler set
+ sensu.sensu_go.handler_set:
+ name: notify_all_the_things
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu handler set.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: tcp_udp_handler_minimum
+ namespace: default
+ handlers:
+ - slack
+ type: set
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ required_if = [
+ ('state', 'present', ['handlers'])
+ ]
+ module = AnsibleModule(
+ supports_check_mode=True,
+ required_if=required_if,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth", "name", "state", "labels", "annotations", "namespace",
+ ),
+ handlers=dict(
+ type='list', elements='str',
+ ),
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ module.params['namespace'], 'handlers', module.params['name'],
+ )
+ payload = arguments.get_mutation_payload(
+ module.params, 'handlers'
+ )
+ payload['type'] = 'set'
+
+ try:
+ changed, handler = utils.sync(
+ module.params['state'], client, path, payload, module.check_mode,
+ )
+ module.exit_json(changed=changed, object=handler)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/hook.py b/ansible_collections/sensu/sensu_go/plugins/modules/hook.py
new file mode 100644
index 00000000..b78f90da
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/hook.py
@@ -0,0 +1,149 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: hook
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu hooks
+description:
+ - Create, update or delete Sensu hook.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/hooks/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+ - sensu.sensu_go.labels
+ - sensu.sensu_go.annotations
+seealso:
+ - module: sensu.sensu_go.hook_info
+options:
+ command:
+ description:
+ - Command to run when the hook is triggered.
+ - Required if I(state) is C(present).
+ type: str
+ timeout:
+ description:
+ - The hook execution duration timeout in seconds (hard stop).
+ - Required if I(state) is C(present).
+ type: int
+ stdin:
+ description:
+ - Controls whether Sensu writes serialized JSON data to the process's stdin.
+ type: bool
+ runtime_assets:
+ description:
+ - List of runtime assets required to run the check.
+ type: list
+ elements: str
+'''
+
+EXAMPLES = '''
+- name: Rudimentary auto-remediation hook
+ sensu.sensu_go.hook:
+ auth:
+ url: http://localhost:8080
+ name: restart_nginx
+ command: sudo systemctl start nginx
+ timeout: 60
+ stdin: false
+
+- name: Capture the process tree
+ sensu.sensu_go.hook:
+ auth:
+ url: http://localhost:8080
+ name: process_tree
+ command: ps aux
+ timeout: 60
+ stdin: false
+
+- name: Delete a hook
+ sensu.sensu_go.hook:
+ name: process_tree
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu hook.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ annotations: null
+ labels: null
+ name: restart_nginx
+ namespace: default
+ command: sudo systemctl start nginx
+ stdin: false
+ timeout: 60
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ required_if = [
+ ('state', 'present', ['command', 'timeout'])
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth", "name", "state", "labels", "annotations", "namespace",
+ ),
+ command=dict(),
+ timeout=dict(
+ type='int',
+ ),
+ stdin=dict(
+ type='bool'
+ ),
+ runtime_assets=dict(
+ type='list', elements='str',
+ ),
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ module.params['namespace'], 'hooks', module.params['name'],
+ )
+ payload = arguments.get_mutation_payload(
+ module.params, 'command', 'timeout', 'stdin', 'runtime_assets'
+ )
+ try:
+ changed, hook = utils.sync(
+ module.params['state'], client, path, payload, module.check_mode,
+ )
+ module.exit_json(changed=changed, object=hook)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/hook_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/hook_info.py
new file mode 100644
index 00000000..f576a5e4
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/hook_info.py
@@ -0,0 +1,95 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: hook_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu hooks
+description:
+ - Retrieve information about Sensu hooks.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/hooks/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.hook
+'''
+
+EXAMPLES = '''
+- name: List all Sensu hooks
+ sensu.sensu_go.hook_info:
+ register: result
+
+- name: Fetch a specific Sensu hook
+ sensu.sensu_go.hook_info:
+ name: awesome-hook
+ register: result
+'''
+
+RETURN = '''
+objects:
+ description: List of Sensu hooks.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ annotations: null
+ labels: null
+ name: restart_nginx
+ namespace: default
+ command: sudo systemctl start nginx
+ stdin: false
+ timeout: 60
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "hooks", module.params["name"],
+ )
+
+ try:
+ hooks = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=hooks)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/ldap_auth_provider.py b/ansible_collections/sensu/sensu_go/plugins/modules/ldap_auth_provider.py
new file mode 100644
index 00000000..e0ee4da0
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/ldap_auth_provider.py
@@ -0,0 +1,378 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2020, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: ldap_auth_provider
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Miha Dolinar (@mdolin)
+ - Tadej Borovsak (@tadeboro)
+
+short_description: Manage Sensu LDAP authentication provider
+
+description:
+ - Create, update or delete a Sensu Go LDAP authentication provider.
+ - For more information, refer to the Sensu Go documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/control-access/ldap-auth/).
+
+version_added: 1.10.0
+
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.state
+
+options:
+ servers:
+ description:
+ - An array of LDAP servers for your directory.
+ - Required if I(state) is C(present).
+ type: list
+ elements: dict
+ suboptions:
+ host:
+ description:
+ - LDAP server IP address.
+ required: true
+ type: str
+ port:
+ description:
+ - LDAP server port.
+ type: int
+ insecure:
+ description:
+ - Skips SSL certificate verification when set to true.
+ type: bool
+ default: false
+ security:
+ description:
+ - Encryption type to be used for the connection to the LDAP server.
+ type: str
+ choices: [ insecure, tls, starttls ]
+ default: tls
+ trusted_ca_file:
+ description:
+ - Path to an alternative CA bundle file.
+ type: str
+ client_cert_file:
+ description:
+ - Path to the certificate that should be sent to the server if requested.
+ type: str
+ client_key_file:
+ description:
+ - Path to the key file associated with the client_cert_file.
+ - Required if I(client_cert_file) is present.
+ type: str
+ binding:
+ description:
+ - The LDAP account that performs user and group lookups.
+ - If your sever supports anonymous binding, you can omit the user_dn or password
+ attributes to query the directory without credentials.
+ type: dict
+ suboptions:
+ user_dn:
+ description:
+ - The LDAP account that performs user and group lookups.
+ - If your sever supports anonymous binding, you can omit this attribute.
+ type: str
+ required: true
+ password:
+ description:
+ - Password for the user_dn account.
+ - If your sever supports anonymous binding, you can omit this attribute.
+ type: str
+ required: true
+ group_search:
+ description:
+ - Search configuration for groups.
+ type: dict
+ suboptions:
+ base_dn:
+ description:
+ - Which part of the directory tree to search.
+ required: true
+ type: str
+ attribute:
+ description:
+ - Used for comparing result entries.
+ type: str
+ default: member
+ name_attribute:
+ description:
+ - Represents the attribute to use as the entry name.
+ type: str
+ default: cn
+ object_class:
+ description:
+ - Identifies the class of objects returned in the search result.
+ type: str
+ default: groupOfNames
+ user_search:
+ description:
+ - Search configuration for users.
+ type: dict
+ suboptions:
+ base_dn:
+ description:
+ - Which part of the directory tree to search.
+ required: true
+ type: str
+ attribute:
+ description:
+ - Used for comparing result entries.
+ type: str
+ default: uid
+ name_attribute:
+ description:
+ - Represents the attribute to use as the entry name.
+ type: str
+ default: cn
+ object_class:
+ description:
+ - Identifies the class of objects returned in the search result.
+ type: str
+ default: person
+ groups_prefix:
+ description:
+ - The prefix added to all LDAP groups.
+ type: str
+ username_prefix:
+ description:
+ - The prefix added to all LDAP usernames.
+ type: str
+
+seealso:
+ - module: sensu.sensu_go.auth_provider_info
+ - module: sensu.sensu_go.ad_auth_provider
+ - module: sensu.sensu_go.oidc_auth_provider
+"""
+
+EXAMPLES = """
+- name: Create a LDAP auth provider
+ sensu.sensu_go.ldap_auth_provider:
+ name: openldap
+ servers:
+ - host: 127.0.0.1
+ group_search:
+ base_dn: dc=acme,dc=org
+ user_search:
+ base_dn: dc=acme,dc=org
+
+- name: Delete a LDAP auth provider
+ sensu.sensu_go.ldap_auth_provider:
+ name: openldap
+ state: absent
+"""
+
+RETURN = """
+object:
+ description: Object representing Sensu LDAP authentication provider.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: 'openldap'
+ servers:
+ host: '127.0.0.1'
+ port: '636'
+ insecure: 'False'
+ security: 'tls'
+ trusted_ca_file: '/path/to/trusted-certificate-authorities.pem'
+ client_cert_file: '/path/to/ssl/cert.pem'
+ client_key_file: '/path/to/ssl/key.pem'
+ binding:
+ user_dn: 'cn=binder,dc=acme,dc=org'
+ group_search:
+ base_dn: 'dc=acme,dc=org'
+ attribute: 'member'
+ name_attribute': 'cn'
+ object_class: 'groupOfNames'
+ user_search:
+ base_dn: 'dc=acme,dc=org'
+ attribute: 'uid'
+ name_attribute: 'cn'
+ object_class: 'person'
+ groups_prefix: 'ldap'
+ username_prefix: 'ldap'
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "authentication/v2"
+
+
+def remove_item(result):
+ if result:
+ for server in result["servers"]:
+ if server["binding"] and "password" in server["binding"]:
+ del server["binding"]["password"]
+
+ return result
+
+
+def _filter(payload):
+ # Remove keys with None values from dict
+ return dict((k, v) for k, v in payload.items() if v is not None)
+
+
+def do_differ(current, desired):
+ if utils.do_differ_v1(current, desired, "servers"):
+ return True
+
+ if len(current["spec"]["servers"]) != len(desired["spec"]["servers"]):
+ return True
+
+ for c, d in zip(current["spec"]["servers"], desired["spec"]["servers"]):
+ if utils.do_differ(c, _filter(d)):
+ return True
+
+ return False
+
+
+def main():
+ required_if = [("state", "present", ["servers"])]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth",
+ "name",
+ "state",
+ ),
+ servers=dict(
+ type="list",
+ elements="dict",
+ options=dict(
+ host=dict(
+ type="str",
+ required=True,
+ ),
+ port=dict(
+ type="int",
+ ),
+ insecure=dict(
+ type="bool",
+ default=False,
+ ),
+ security=dict(
+ type="str",
+ choices=["insecure", "tls", "starttls"],
+ default="tls",
+ ),
+ trusted_ca_file=dict(
+ type="str",
+ ),
+ client_cert_file=dict(
+ type="str",
+ ),
+ client_key_file=dict(
+ type="str",
+ ),
+ binding=dict(
+ type="dict",
+ options=dict(
+ user_dn=dict(
+ type="str",
+ required=True,
+ ),
+ password=dict(
+ type="str",
+ no_log=True,
+ required=True,
+ ),
+ ),
+ ),
+ group_search=dict(
+ type="dict",
+ options=dict(
+ base_dn=dict(
+ type="str",
+ required=True,
+ ),
+ attribute=dict(
+ type="str",
+ default="member",
+ ),
+ name_attribute=dict(
+ type="str",
+ default="cn",
+ ),
+ object_class=dict(type="str", default="groupOfNames"),
+ ),
+ ),
+ user_search=dict(
+ type="dict",
+ options=dict(
+ base_dn=dict(
+ type="str",
+ required=True,
+ ),
+ attribute=dict(
+ type="str",
+ default="uid",
+ ),
+ name_attribute=dict(
+ type="str",
+ default="cn",
+ ),
+ object_class=dict(
+ type="str",
+ default="person",
+ ),
+ ),
+ ),
+ ),
+ ),
+ groups_prefix=dict(
+ type="str",
+ ),
+ username_prefix=dict(
+ type="str",
+ ),
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, "authproviders", module.params["name"]
+ )
+
+ payload = dict(
+ type="ldap",
+ api_version=API_VERSION,
+ metadata=dict(name=module.params["name"]),
+ spec=arguments.get_spec_payload(
+ module.params, "servers", "groups_prefix", "username_prefix"
+ ),
+ )
+
+ try:
+ changed, ldap_provider = utils.sync_v1(
+ module.params["state"], client, path, payload, module.check_mode, do_differ
+ )
+ module.exit_json(changed=changed, object=remove_item(ldap_provider))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/mutator.py b/ansible_collections/sensu/sensu_go/plugins/modules/mutator.py
new file mode 100644
index 00000000..0baf8ca8
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/mutator.py
@@ -0,0 +1,154 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: mutator
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu mutators
+description:
+ - Create, update or delete Sensu mutator.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/mutators/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+ - sensu.sensu_go.labels
+ - sensu.sensu_go.annotations
+ - sensu.sensu_go.secrets
+seealso:
+ - module: sensu.sensu_go.mutator_info
+options:
+ command:
+ description:
+ - The mutator command to be executed by the Sensu backend.
+ - Required if I(state) is C(present).
+ type: str
+ timeout:
+ description:
+ - The mutator execution duration timeout in seconds (hard stop).
+ type: int
+ env_vars:
+ description:
+ - A mapping of environment variable names and values to use with command execution.
+ type: dict
+ runtime_assets:
+ description:
+ - List of runtime assets, required to run the mutator I(command).
+ type: list
+ elements: str
+'''
+
+EXAMPLES = '''
+- name: Create a mutator
+ sensu.sensu_go.mutator:
+ name: mutator
+ command: sensu-influxdb-mutator
+ timeout: 30
+ env_vars:
+ INFLUXDB_ADDR: http://influxdb.default.svc.cluster.local:8086
+ INFLUXDB_USER: sensu
+ runtime_assets:
+ - sensu-influxdb-mutator
+
+- name: Delete a mutator
+ sensu.sensu_go.mutator:
+ name: mutator
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu mutator.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ annotations: null
+ labels: null
+ name: example-mutator
+ namespace: default
+ command: example_mutator.go
+ env_vars: []
+ runtime_assets: []
+ timeout: 0
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def do_differ(current, desired):
+ return (
+ utils.do_differ(current, desired, "secrets") or
+ utils.do_secrets_differ(current, desired)
+ )
+
+
+def main():
+ required_if = [
+ ('state', 'present', ['command'])
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth", "name", "state", "labels", "annotations", "namespace",
+ "secrets",
+ ),
+ command=dict(),
+ timeout=dict(
+ type='int',
+ ),
+ env_vars=dict(
+ type='dict'
+ ),
+ runtime_assets=dict(
+ type='list', elements='str',
+ ),
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ module.params['namespace'], 'mutators', module.params['name'],
+ )
+ payload = arguments.get_mutation_payload(
+ module.params, 'command', 'timeout', 'runtime_assets', 'secrets',
+ )
+ if module.params['env_vars']:
+ payload['env_vars'] = utils.dict_to_key_value_strings(module.params['env_vars'])
+ try:
+ changed, mutator = utils.sync(
+ module.params['state'], client, path, payload, module.check_mode,
+ do_differ,
+ )
+ module.exit_json(changed=changed, object=mutator)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/mutator_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/mutator_info.py
new file mode 100644
index 00000000..1e247205
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/mutator_info.py
@@ -0,0 +1,96 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: mutator_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu mutators
+description:
+ - Retrieve information about Sensu mutators.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/mutators/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.mutator
+'''
+
+EXAMPLES = '''
+- name: List all Sensu mutators
+ sensu.sensu_go.mutator_info:
+ register: result
+
+- name: Retrieve a single Sensu mutator
+ sensu.sensu_go.mutator_info:
+ name: my-mutator
+ register: result
+'''
+
+RETURN = '''
+objects:
+ description: List of Sensu mutators.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ annotations: null
+ labels: null
+ name: example-mutator
+ namespace: default
+ command: example_mutator.go
+ env_vars: []
+ runtime_assets: []
+ timeout: 0
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "mutators", module.params["name"],
+ )
+
+ try:
+ mutators = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=mutators)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/namespace.py b/ansible_collections/sensu/sensu_go/plugins/modules/namespace.py
new file mode 100644
index 00000000..64d174cb
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/namespace.py
@@ -0,0 +1,87 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: namespace
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu namespaces
+description:
+ - Create, update or delete a Sensu namespace.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#namespaces).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.state
+seealso:
+ - module: sensu.sensu_go.namespace_info
+'''
+
+EXAMPLES = '''
+- name: Create a new namespace
+ sensu.sensu_go.namespace:
+ name: production
+ state: present
+
+- name: Delete a namespace
+ sensu.sensu_go.namespace:
+ name: staging
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu namespace.
+ returned: success
+ type: dict
+ sample:
+ name: default
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=arguments.get_spec("auth", "name", "state"),
+ )
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ None, 'namespaces', module.params['name'],
+ )
+ payload = arguments.get_spec_payload(
+ module.params, 'name'
+ )
+ try:
+ changed, namespace = utils.sync(
+ module.params['state'], client, path, payload, module.check_mode,
+ )
+ module.exit_json(changed=changed, object=namespace)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/namespace_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/namespace_info.py
new file mode 100644
index 00000000..d5d0a269
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/namespace_info.py
@@ -0,0 +1,79 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: namespace_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu namespaces
+description:
+ - Retrieve information about Sensu namespaces.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#namespaces).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+notes:
+ - Currently, it is not possible to retrieve information about a single
+ namespace because namespace is not much more than a name itself.
+seealso:
+ - module: sensu.sensu_go.namespace
+'''
+
+EXAMPLES = '''
+- name: List Sensu namespaces
+ sensu.sensu_go.namespace_info:
+ register: result
+'''
+
+RETURN = '''
+objects:
+ description: List of Sensu namespaces.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - name: default
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth"),
+ ),
+ )
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(None, 'namespaces')
+
+ try:
+ namespaces = utils.get(client, path)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=namespaces)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/oidc_auth_provider.py b/ansible_collections/sensu/sensu_go/plugins/modules/oidc_auth_provider.py
new file mode 100644
index 00000000..bcd5d4ed
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/oidc_auth_provider.py
@@ -0,0 +1,248 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2020, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: oidc_auth_provider
+
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Miha Dolinar (@mdolin)
+ - Tadej Borovsak (@tadeboro)
+
+short_description: Manage Sensu OIDC authentication provider
+
+description:
+ - Create, update or delete a Sensu Go OIDC authentication provider.
+ - For more information, refer to the Sensu Go documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/control-access/oidc-auth/).
+
+version_added: 1.10.0
+
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.state
+
+options:
+ additional_scopes:
+ description:
+ - Scopes to include in the claims.
+ type: list
+ elements: str
+ default: openid
+ client_id:
+ description:
+ - The OIDC provider application Client ID.
+ - Required if I(state) is C(present).
+ type: str
+ client_secret:
+ description:
+ - The OIDC provider application Client Secret.
+ - Required if I(state) is C(present).
+ type: str
+ disable_offline_access:
+ description:
+ - If C(true), the OIDC provider cannot include the offline_access scope
+ in the authentication request. Otherwise, C(false).
+ type: bool
+ default: false
+ redirect_uri:
+ description:
+ - Redirect URL to provide to the OIDC provider.
+ type: str
+ server:
+ description:
+ - The location of the OIDC server you wish to authenticate against.
+ - Required if I(state) is C(present).
+ type: str
+ groups_claim:
+ description:
+ - The claim to use to form the associated RBAC groups.
+ type: str
+ groups_prefix:
+ description:
+ - The prefix added to all OIDC groups.
+ type: str
+ username_claim:
+ description:
+ - The claim to use to form the final RBAC user name.
+ - Required if I(state) is C(present).
+ type: str
+ username_prefix:
+ description:
+ - The prefix added to all OIDC usernames.
+ type: str
+
+seealso:
+ - module: sensu.sensu_go.auth_provider_info
+ - module: sensu.sensu_go.ldap_auth_provider
+ - module: sensu.sensu_go.ad_auth_provider
+
+notes:
+ - Supported only on Sensu Go versions >= 6.
+"""
+
+EXAMPLES = """
+- name: Create a OIDC auth provider
+ sensu.sensu_go.oidc_auth_provider:
+ state: present
+ name: oidc_name
+ additional_scopes:
+ - groups
+ - email
+ client_id: a8e43af034e7f2608780
+ client_secret: b63968394be6ed2edb61c93847ee792f31bf6216
+ disable_offline_access: false
+ redirect_uri: http://127.0.0.1:8080/api/enterprise/authentication/v2/oidc/callback
+ server: https://oidc.example.com:9031
+ groups_claim: groups
+ groups_prefix: 'oidc:'
+ username_claim: email
+ username_prefix: 'oidc:'
+
+- name: Delete a OIDC auth provider
+ sensu.sensu_go.oidc_auth_provider:
+ name: oidc_name
+ state: absent
+"""
+
+RETURN = """
+object:
+ description: Object representing Sensu OIDC authentication provider.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: 'oidc_name'
+ created_by: 'admin'
+ additional_scopes:
+ - 'groups'
+ - 'email'
+ client_id: 'a8e43af034e7f2608780'
+ disable_offline_access: false
+ redirect_uri: 'http://sensu-backend.example.com:8080/api/enterprise/authentication/v2/oidc/callback'
+ server: 'https://oidc.example.com:9031'
+ groups_claim: 'groups'
+ groups_prefix: 'oidc:'
+ username_claim: 'email'
+ username_prefix: 'oidc:'
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "authentication/v2"
+
+
+def remove_item(result):
+ if result and 'client_secret' in result:
+ del result['client_secret']
+
+ return result
+
+
+def main():
+ required_if = [
+ ("state", "present", ["client_id", "client_secret", "server", "username_claim"])
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth",
+ "name",
+ "state",
+ ),
+ additional_scopes=dict(
+ type="list",
+ elements="str",
+ default="openid",
+ ),
+ client_id=dict(
+ type="str",
+ ),
+ client_secret=dict(
+ type="str",
+ no_log=True,
+ ),
+ disable_offline_access=dict(
+ type="bool",
+ default=False,
+ ),
+ redirect_uri=dict(
+ type="str",
+ ),
+ server=dict(
+ type="str",
+ ),
+ groups_claim=dict(
+ type="str",
+ ),
+ groups_prefix=dict(
+ type="str",
+ ),
+ username_claim=dict(
+ type="str",
+ ),
+ username_prefix=dict(
+ type="str",
+ ),
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, "authproviders", module.params["name"]
+ )
+
+ payload = dict(
+ type="oidc",
+ api_version=API_VERSION,
+ metadata=dict(name=module.params["name"]),
+ spec=arguments.get_spec_payload(
+ module.params,
+ "additional_scopes",
+ "client_id",
+ "client_secret",
+ "disable_offline_access",
+ "redirect_uri",
+ "server",
+ "groups_claim",
+ "groups_prefix",
+ "username_claim",
+ "username_prefix",
+ ),
+ )
+
+ try:
+ changed, oidc_provider = utils.sync_v1(
+ module.params["state"], client, path, payload, module.check_mode
+ )
+ module.exit_json(
+ changed=changed, object=remove_item(oidc_provider)
+ )
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/pipe_handler.py b/ansible_collections/sensu/sensu_go/plugins/modules/pipe_handler.py
new file mode 100644
index 00000000..99e985f7
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/pipe_handler.py
@@ -0,0 +1,167 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: pipe_handler
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu pipe handler
+description:
+ - Create, update or delete a Sensu pipe handler.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/handlers/#pipe-handlers).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+ - sensu.sensu_go.labels
+ - sensu.sensu_go.annotations
+ - sensu.sensu_go.secrets
+seealso:
+ - module: sensu.sensu_go.socket_handler
+ - module: sensu.sensu_go.handler_info
+ - module: sensu.sensu_go.handler_set
+options:
+ command:
+ description:
+ - The handler command to be executed. The event data is passed to the
+ process through STDIN.
+ - Required if I(state) is C(present).
+ type: str
+ filters:
+ description:
+ - List of filters to use when determining whether to pass the check result to this handler.
+ type: list
+ elements: str
+ mutator:
+ description:
+ - Mutator to call for transforming the check result before passing it to this handler.
+ type: str
+ timeout:
+ description:
+ - Timeout for handler execution.
+ type: int
+ env_vars:
+ description:
+ - A mapping of environment variable names and values to use with command execution.
+ type: dict
+ runtime_assets:
+ description:
+ - List of runtime assets to required to run the handler C(command).
+ type: list
+ elements: str
+'''
+
+EXAMPLES = '''
+- name: Setup InfluxDB handler
+ sensu.sensu_go.pipe_handler:
+ name: influx-db
+ command: sensu-influxdb-handler -d sensu
+ env_vars:
+ INFLUXDB_ADDR: http://influxdb.default.svc.cluster.local:8086
+ INFLUXDB_USER: sensu
+ INFLUXDB_PASS: password
+ runtime_assets:
+ - sensu-influxdb-handler
+
+- name: Delete handler
+ sensu.sensu_go.pipe_handler:
+ name: influx-db
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu pipe handler.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: pipe_handler_minimum
+ namespace: default
+ command: command-example
+ type: pipe
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def do_differ(current, desired):
+ return (
+ utils.do_differ(current, desired, "secrets") or
+ utils.do_secrets_differ(current, desired)
+ )
+
+
+def main():
+ required_if = [
+ ('state', 'present', ['command'])
+ ]
+ module = AnsibleModule(
+ supports_check_mode=True,
+ required_if=required_if,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth", "name", "state", "labels", "annotations", "namespace",
+ "secrets",
+ ),
+ command=dict(),
+ filters=dict(
+ type='list', elements='str',
+ ),
+ mutator=dict(),
+ timeout=dict(
+ type='int'
+ ),
+ env_vars=dict(
+ type='dict'
+ ),
+ runtime_assets=dict(
+ type='list', elements='str',
+ ),
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ module.params['namespace'], 'handlers', module.params['name'],
+ )
+ payload = arguments.get_mutation_payload(
+ module.params, 'command', 'filters', 'mutator', 'timeout',
+ 'runtime_assets', 'secrets',
+ )
+ payload['type'] = 'pipe'
+ if module.params['env_vars']:
+ payload['env_vars'] = utils.dict_to_key_value_strings(module.params['env_vars'])
+
+ try:
+ changed, handler = utils.sync(
+ module.params['state'], client, path, payload, module.check_mode,
+ do_differ,
+ )
+ module.exit_json(changed=changed, object=handler)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/role.py b/ansible_collections/sensu/sensu_go/plugins/modules/role.py
new file mode 100644
index 00000000..54f58d13
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/role.py
@@ -0,0 +1,165 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: role
+author:
+ - Paul Arthur (@flowerysong)
+ - Manca Bizjak (@mancabizjak)
+ - Aljaz Kosir (@aljazkosir)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu roles
+description:
+ - Create, update or delete Sensu role.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#roles-and-cluster-roles).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+seealso:
+ - module: sensu.sensu_go.role_info
+ - module: sensu.sensu_go.cluster_role
+ - module: sensu.sensu_go.role_binding
+options:
+ rules:
+ description:
+ - Rules that the role applies.
+ - Must be non-empty if I(state) is C(present).
+ type: list
+ elements: dict
+ suboptions:
+ verbs:
+ description:
+ - Permissions to be applied by the rule.
+ type: list
+ elements: str
+ required: yes
+ choices: [get, list, create, update, delete]
+ resources:
+ description:
+ - Types of resources the rule has permission to access.
+ type: list
+ elements: str
+ required: yes
+ resource_names:
+ description:
+ - Names of specific resources the rule has permission to access.
+ - Note that for the C(create) verb, this argument will not be
+ taken into account when enforcing RBAC, even if it is provided.
+ type: list
+ elements: str
+'''
+
+EXAMPLES = '''
+- name: Create a role
+ sensu.sensu_go.role:
+ name: readonly
+ rules:
+ - verbs:
+ - get
+ - list
+ resources:
+ - checks
+ - entities
+
+- name: Delete a role
+ sensu.sensu_go.role:
+ name: readonly
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu role.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: namespaced-resources-all-verbs
+ namespace: default
+ rules:
+ - resource_names: []
+ resources:
+ - assets
+ - checks
+ verbs:
+ - create
+ - update
+ - delete
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils, role_utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "name", "state", "namespace"),
+ rules=dict(
+ type="list",
+ elements="dict",
+ options=dict(
+ verbs=dict(
+ required=True,
+ type="list",
+ elements="str",
+ choices=["get", "list", "create", "update", "delete"],
+ ),
+ resources=dict(
+ required=True,
+ type="list",
+ elements="str",
+ ),
+ resource_names=dict(
+ type="list",
+ elements="str",
+ ),
+ )
+ )
+ )
+ )
+
+ msg = role_utils.validate_module_params(module.params)
+ if msg:
+ module.fail_json(msg=msg)
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "roles", module.params["name"],
+ )
+ payload = arguments.get_mutation_payload(
+ module.params, "rules"
+ )
+
+ try:
+ changed, role = utils.sync(
+ module.params['state'], client, path,
+ payload, module.check_mode, role_utils.do_roles_differ
+ )
+ module.exit_json(changed=changed, object=role)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/role_binding.py b/ansible_collections/sensu/sensu_go/plugins/modules/role_binding.py
new file mode 100644
index 00000000..0bab8b1b
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/role_binding.py
@@ -0,0 +1,176 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: role_binding
+author:
+ - Paul Arthur (@flowerysong)
+ - Manca Bizjak (@mancabizjak)
+ - Aljaz Kosir (@aljazkosir)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu role bindings
+description:
+ - Create, update or delete Sensu role binding.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#role-bindings-and-cluster-role-bindings).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+seealso:
+ - module: sensu.sensu_go.role_binding_info
+ - module: sensu.sensu_go.role
+ - module: sensu.sensu_go.cluster_role
+ - module: sensu.sensu_go.cluster_role_binding
+options:
+ role:
+ description:
+ - Name of the role.
+ - This parameter is mutually exclusive with I(cluster_role).
+ type: str
+ cluster_role:
+ description:
+ - Name of the cluster role. Note that the resulting role
+ binding grants the cluster role to the provided users and
+ groups in the context of I(auth.namespace) only.
+ - This parameter is mutually exclusive with I(role).
+ type: str
+ users:
+ description:
+ - List of users to bind to the role or cluster role.
+ - Note that at least one of I(users) and I(groups) must be
+ specified when creating a role binding.
+ type: list
+ elements: str
+ groups:
+ description:
+ - List of groups to bind to the role or cluster role.
+ - Note that at least one of I(users) and I(groups) must be
+ specified when creating a role binding.
+ type: list
+ elements: str
+'''
+
+EXAMPLES = '''
+- name: Create a role binding
+ sensu.sensu_go.role_binding:
+ name: dev_and_testing
+ role: testers_permissive
+ groups:
+ - testers
+ - dev
+ - ops
+ users:
+ - alice
+
+- name: Create a role binding for admins
+ sensu.sensu_go.role_binding:
+ name: org-admins
+ cluster_role: admin
+ groups:
+ - team1-admins
+ - team2-admins
+
+- name: Delete a role binding
+ sensu.sensu_go.role_binding:
+ name: org-admins
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu role binding.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: event-reader-binding
+ namespace: default
+ role_ref:
+ name: event-reader
+ type: Role
+ subjects:
+ - name: bob
+ type: User
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils, role_utils
+
+
+def infer_role(params):
+ if params["role"]:
+ return "Role", params["role"]
+ return "ClusterRole", params["cluster_role"]
+
+
+def build_api_payload(params):
+ payload = arguments.get_mutation_payload(params)
+ payload["subjects"] = role_utils.build_subjects(params["groups"], params["users"])
+ payload["role_ref"] = role_utils.type_name_dict(*infer_role(params))
+
+ return payload
+
+
+def main():
+ required_if = [
+ ("state", "present", ["role", "cluster_role"], True) # True means any of role, cluster_role
+ ]
+ mutually_exclusive = [
+ ["role", "cluster_role"]
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ mutually_exclusive=mutually_exclusive,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "name", "state", "namespace"),
+ role=dict(),
+ cluster_role=dict(),
+ users=dict(
+ type="list", elements="str",
+ ),
+ groups=dict(
+ type="list", elements="str",
+ ),
+ )
+ )
+
+ msg = role_utils.validate_binding_module_params(module.params)
+ if msg:
+ module.fail_json(msg=msg)
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "rolebindings", module.params["name"],
+ )
+ payload = build_api_payload(module.params)
+
+ try:
+ changed, role_binding = utils.sync(
+ module.params["state"], client, path, payload, module.check_mode, role_utils.do_role_bindings_differ
+ )
+ module.exit_json(changed=changed, object=role_binding)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/role_binding_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/role_binding_info.py
new file mode 100644
index 00000000..ef7d230f
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/role_binding_info.py
@@ -0,0 +1,97 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: role_binding_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Manca Bizjak (@mancabizjak)
+ - Aljaz Kosir (@aljazkosir)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu role bindings
+description:
+ - Retrieve information about Sensu role bindings.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#role-bindings-and-cluster-role-bindings).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.role_binding
+'''
+
+EXAMPLES = '''
+- name: List all Sensu role bindings
+ sensu.sensu_go.role_binding_info:
+ register: result
+
+- name: Retrieve a single Sensu role binding
+ sensu.sensu_go.role_binding_info:
+ name: my-role-binding
+ register: result
+'''
+
+RETURN = '''
+role_bindings:
+ description: List of Sensu role bindings.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: event-reader-binding
+ namespace: default
+ role_ref:
+ name: event-reader
+ type: Role
+ subjects:
+ - name: bob
+ type: User
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ name=dict()
+ )
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "rolebindings", module.params["name"],
+ )
+
+ try:
+ role_bindings = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=role_bindings)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/role_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/role_info.py
new file mode 100644
index 00000000..cf2c7e8f
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/role_info.py
@@ -0,0 +1,100 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: role_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Manca Bizjak (@mancabizjak)
+ - Aljaz Kosir (@aljazkosir)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu roles
+description:
+ - Retrieve information about Sensu roles.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#roles-and-cluster-roles).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.role
+'''
+
+EXAMPLES = '''
+- name: List all Sensu roles
+ sensu.sensu_go.role_info:
+ register: result
+
+- name: Retrieve a specific Sensu role
+ sensu.sensu_go.role_info:
+ name: my-role
+ register: result
+'''
+
+RETURN = '''
+roles:
+ description: List of Sensu roles.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: namespaced-resources-all-verbs
+ namespace: default
+ rules:
+ - resource_names: []
+ resources:
+ - assets
+ - checks
+ verbs:
+ - create
+ - update
+ - delete
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ name=dict()
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "roles", module.params["name"],
+ )
+
+ try:
+ roles = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=roles)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/secret.py b/ansible_collections/sensu/sensu_go/plugins/modules/secret.py
new file mode 100644
index 00000000..6b012557
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/secret.py
@@ -0,0 +1,131 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2020, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: secret
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Miha Dolinar (@mdolin)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu Go secrets
+description:
+ - Create, update or delete Sensu secret.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/manage-secrets/secrets/).
+version_added: 1.6.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+seealso:
+ - module: sensu.sensu_go.secret_info
+ - module: sensu.sensu_go.secrets_provider_env
+ - module: sensu.sensu_go.secrets_provider_vault
+ - module: sensu.sensu_go.secrets_provider_info
+options:
+ provider:
+ description:
+ - Name of the secrets provider that backs the secret value.
+ - Required if I(state) is C(present).
+ type: str
+ id:
+ description:
+ - Secret's id in the provider store.
+ - Required if I(state) is C(present).
+ type: str
+"""
+
+EXAMPLES = """
+- name: Create an environment varibale-backed secret
+ sensu.sensu_go.secret:
+ name: env_secret
+ provider: env
+ id: MY_ENV_VARIABLE
+
+- name: Create a HashiCorp Vault-backed secret
+ sensu.sensu_go.secret:
+ name: hashi_valut_secret
+ provider: vault
+ id: secret/store#name
+
+- name: Delete a secret
+ sensu.sensu_go.secret:
+ name: my_secret
+ state: absent
+"""
+
+RETURN = """
+object:
+ description: Object representing Sensu secret.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: sensu-ansible
+ namespace: default
+ id: 'secret/database#password'
+ provider: vault
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "secrets/v1"
+
+
+def main():
+ required_if = [
+ ("state", "present", ["provider", "id"])
+ ]
+ module = AnsibleModule(
+ required_if=required_if,
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "name", "state", "namespace"),
+ provider=dict(type="str"),
+ id=dict(type="str"),
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, module.params["namespace"], "secrets",
+ module.params["name"],
+ )
+ payload = dict(
+ type="Secret",
+ api_version=API_VERSION,
+ metadata=dict(
+ name=module.params["name"],
+ namespace=module.params["namespace"],
+ ),
+ spec=arguments.get_spec_payload(module.params, "provider", "id"),
+ )
+ try:
+ changed, secret = utils.sync_v1(
+ module.params["state"], client, path, payload, module.check_mode,
+ )
+ module.exit_json(changed=changed, object=secret)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/secret_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/secret_info.py
new file mode 100644
index 00000000..a16ca82a
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/secret_info.py
@@ -0,0 +1,110 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2020, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: secret_info
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Miha Dolinar (@mdolin)
+ - Tadej Borovsak (@tadeboro)
+short_description: List available Sensu Go secrets
+description:
+ - Retrieve information about Sensu Go secrets.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/manage-secrets/secrets/).
+version_added: 1.6.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.secret
+ - module: sensu.sensu_go.secrets_provider_env
+ - module: sensu.sensu_go.secrets_provider_vault
+ - module: sensu.sensu_go.secrets_provider_info
+"""
+
+EXAMPLES = """
+- name: List all Sensu Go secrets
+ sensu.sensu_go.secret_info:
+ register: result
+
+- name: Retrieve the selected Sensu Go secret
+ sensu.sensu_go.secret_info:
+ name: my-secret
+ register: result
+
+- name: Do something with result
+ ansible.builtin.debug:
+ msg: "{{ result.objects.0.id }}"
+"""
+
+RETURN = """
+objects:
+ description: List of Sensu Go secrets.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: sensu-ansible-token
+ namespace: default
+ id: ANSIBLE_TOKEN
+ provider: env
+ - metadata:
+ name: sensu-ansible
+ namespace: default
+ id: 'secret/database#password'
+ provider: vault
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "secrets/v1"
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "namespace"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, module.params["namespace"], "secrets",
+ module.params["name"],
+ )
+
+ try:
+ secrets = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ # We simulate the behavior of v2 API here and only return the spec.
+ module.exit_json(changed=False, objects=[
+ utils.convert_v1_to_v2_response(s) for s in secrets
+ ])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_env.py b/ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_env.py
new file mode 100644
index 00000000..258b6db0
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_env.py
@@ -0,0 +1,98 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2020, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: secrets_provider_env
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Miha Dolinar (@mdolin)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu Env secrets provider
+description:
+ - Create or delete a Sensu Go Env secrets provider.
+ - The module operates on a secrets provider named C(env).
+ - For more information, refer to the Sensu Go documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/manage-secrets/secrets-providers/).
+version_added: 1.6.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.state
+seealso:
+ - module: sensu.sensu_go.secrets_provider_vault
+ - module: sensu.sensu_go.secrets_provider_info
+ - module: sensu.sensu_go.secret
+ - module: sensu.sensu_go.secret_info
+'''
+
+EXAMPLES = '''
+- name: Create the env secrets provider
+ sensu.sensu_go.secrets_provider_env:
+
+- name: Delete the env secrets provider
+ sensu.sensu_go.secrets_provider_env:
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu Env secrets provider.
+ returned: success
+ type: dict
+ sample:
+ - metadata:
+ name: env
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "secrets/v1"
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth", "state",
+ ),
+ )
+ )
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, 'providers', 'env'
+ )
+ payload = dict(
+ type="Env",
+ api_version=API_VERSION,
+ metadata=dict(name='env'),
+ spec={},
+ )
+
+ try:
+ changed, env_provider = utils.sync_v1(
+ module.params['state'], client, path, payload, module.check_mode,
+ )
+ module.exit_json(changed=changed, object=env_provider)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_info.py
new file mode 100644
index 00000000..b3aa1b0e
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_info.py
@@ -0,0 +1,111 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2020, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = """
+module: secrets_provider_info
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Miha Dolinar (@mdolin)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu secrets providers
+description:
+ - Retrieve information about Sensu Go secrets providers.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/manage-secrets/secrets-providers/).
+version_added: 1.6.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+seealso:
+ - module: sensu.sensu_go.secrets_provider_env
+ - module: sensu.sensu_go.secrets_provider_vault
+ - module: sensu.sensu_go.secret
+ - module: sensu.sensu_go.secret_info
+"""
+
+EXAMPLES = """
+- name: List all Sensu secrets providers
+ sensu.sensu_go.secrets_provider_info:
+ register: result
+
+- name: List the selected Sensu secrets provider
+ sensu.sensu_go.secrets_provider_info:
+ name: my_provider
+ register: result
+
+- name: Do something with result
+ ansible.builtin.debug:
+ msg: "{{ result.objects.0.metadata.name }}"
+"""
+
+RETURN = """
+objects:
+ description: List of Sensu secrets providers.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ name: vault
+ client:
+ address: https://vaultserver.example.com:8200
+ token: VAULT_TOKEN
+ version: v1
+ tls:
+ ca_cert: "/etc/ssl/certs/vault_ca_cert.pem"
+ max_retries: 2
+ timeout: 20s
+ rate_limiter:
+ limit: 10
+ burst: 100
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "secrets/v1"
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, "providers", module.params["name"],
+ )
+
+ try:
+ providers = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ # We simulate the behavior of v2 API here and only return the spec.
+ module.exit_json(changed=False, objects=[
+ utils.convert_v1_to_v2_response(p) for p in providers
+ ])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_vault.py b/ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_vault.py
new file mode 100644
index 00000000..2df0a310
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/secrets_provider_vault.py
@@ -0,0 +1,258 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2020, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: secrets_provider_vault
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Miha Dolinar (@mdolin)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu VaultProvider secrets providers
+description:
+ - Create, update or delete a Sensu Go VaultProvider secrets provider.
+ - For more information, refer to the Sensu Go documentation at
+ U(https://docs.sensu.io/sensu-go/latest/operations/manage-secrets/secrets-providers/).
+version_added: 1.6.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.state
+options:
+ address:
+ description:
+ - Address of the Vault server.
+ - Required if I(state) is C(present).
+ type: str
+ token:
+ description:
+ - Authentication token to use with Vault.
+ - Required if I(state) is C(present).
+ type: str
+ version:
+ description:
+ - Version of the Vault key/value store.
+ - Please refer to U(https://www.vaultproject.io/docs/secrets/kv) for
+ additional information.
+ - Required if I(state) is C(present).
+ type: str
+ choices: [v1, v2]
+ timeout:
+ description:
+ - Timeout (in seconds) for connection to Vault server.
+ type: int
+ max_retries:
+ description:
+ - Maximum number of times to retry failed connections to Vault server.
+ type: int
+ rate_limit:
+ description:
+ - Maximum number of secrets requests for per second.
+ type: float
+ burst_limit:
+ description:
+ - Maximum allowed number of secrets requests in a rate interval.
+ type: int
+ tls:
+ description:
+ - TLS configuration for establishing connection with Vault server.
+ type: dict
+ suboptions:
+ ca_cert:
+ description:
+ - Path to the certificate file of the trusted certificate authority.
+ type: str
+ client_cert:
+ description:
+ - Path to the client certificate file.
+ type: str
+ client_key:
+ description:
+ - Path to the client key file.
+ type: str
+ cname:
+ description:
+ - Canonical name for the client.
+ type: str
+
+seealso:
+ - module: sensu.sensu_go.secrets_provider_env
+ - module: sensu.sensu_go.secrets_provider_info
+ - module: sensu.sensu_go.secret
+ - module: sensu.sensu_go.secret_info
+'''
+
+EXAMPLES = '''
+- name: Create a vault secrets provider
+ sensu.sensu_go.secrets_provider_vault:
+ name: my-vault
+ address: https://my-vault.com
+ token: VAULT_TOKEN
+ version: v1
+
+- name: Delete a vault secrets provider
+ sensu.sensu_go.secrets_provider_vault:
+ name: my-vault
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu vault secrets provider.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ name: vault
+ client:
+ address: https://vaultserver.example.com:8200
+ token: VAULT_TOKEN
+ version: v1
+ tls:
+ ca_cert: "/etc/ssl/certs/vault_ca_cert.pem"
+ max_retries: 2
+ timeout: 20s
+ rate_limiter:
+ limit: 10
+ burst: 100
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+API_GROUP = "enterprise"
+API_VERSION = "secrets/v1"
+
+
+def do_differ(current, desired):
+ if utils.do_differ_v1(current, desired, "client"):
+ return True
+
+ current_client = current["spec"]["client"]
+ desired_client = desired["spec"]["client"]
+ # Sensu Go API returns 'agent_address' field in the client spec,
+ # but this field is not meant to be set via the providers API.
+ if utils.do_differ(current_client, desired_client, "agent_address", "tls"):
+ return True
+ # Sensu Go API returns some extra fields in the tls spec.
+ # We ignore them, as they are not meant to be set via the
+ # providers API.
+ return utils.do_differ(current_client["tls"], desired_client.get("tls") or {},
+ "insecure", "tls_server_name", "ca_path")
+
+
+def _format_seconds(seconds):
+ # Sensu API returns the configured timeout as a string, for instance
+ # 30 -> '30s', 60-> '1m0s', 3600 -> '1h0m0s'.
+ h, r = divmod(seconds, 3600)
+ m, s = divmod(r, 60)
+ if h:
+ return "{0}h{1}m{2}s".format(h, m, s)
+ if m:
+ return "{0}m{1}s".format(m, s)
+ return "{0}s".format(seconds)
+
+
+def build_vault_provider_spec(params):
+ if params["state"] == "absent":
+ return {}
+
+ client = arguments.get_spec_payload(
+ params, "address", "token", "version", "max_retries",
+ )
+ if params.get("tls"):
+ client["tls"] = arguments.get_spec_payload(
+ params["tls"], "ca_cert", "client_cert", "client_key", "cname",
+ )
+ if params.get("timeout"):
+ client["timeout"] = _format_seconds(params["timeout"])
+
+ if params.get("rate_limit") or params.get("burst_limit"):
+ client["rate_limiter"] = arguments.get_renamed_spec_payload(
+ params, dict(
+ rate_limit="limit",
+ burst_limit="burst",
+ )
+ )
+
+ return dict(client=client)
+
+
+def main():
+ required_if = [
+ ("state", "present", ["address", "token", "version"])
+ ]
+
+ module = AnsibleModule(
+ supports_check_mode=True,
+ required_if=required_if,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth", "name", "state",
+ ),
+ address=dict(),
+ token=dict(no_log=True),
+ version=dict(
+ choices=["v1", "v2"],
+ ),
+ timeout=dict(
+ type="int",
+ ),
+ max_retries=dict(
+ type="int",
+ ),
+ rate_limit=dict(
+ type="float",
+ ),
+ burst_limit=dict(
+ type="int",
+ ),
+ tls=dict(
+ type="dict",
+ options=dict(
+ ca_cert=dict(),
+ cname=dict(),
+ client_cert=dict(),
+ client_key=dict(no_log=False),
+ )
+ )
+ )
+ )
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_url_path(
+ API_GROUP, API_VERSION, None, 'providers', module.params['name']
+ )
+
+ payload = dict(
+ type="VaultProvider",
+ api_version=API_VERSION,
+ metadata=dict(name=module.params["name"]),
+ spec=build_vault_provider_spec(module.params)
+ )
+
+ try:
+ changed, vault_provider = utils.sync_v1(
+ module.params['state'], client, path, payload, module.check_mode, do_differ
+ )
+ module.exit_json(changed=changed, object=vault_provider)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/silence.py b/ansible_collections/sensu/sensu_go/plugins/modules/silence.py
new file mode 100644
index 00000000..4b287911
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/silence.py
@@ -0,0 +1,172 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: silence
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu silences
+description:
+ - Create, update or delete Sensu silence.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/silencing/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+ - sensu.sensu_go.labels
+ - sensu.sensu_go.annotations
+seealso:
+ - module: sensu.sensu_go.silence_info
+options:
+ subscription:
+ description:
+ - The name of the subscription the entry should match.
+ - If left empty a silencing entry will contain an asterisk in the
+ subscription position. This indicates that any event with a matching
+ check name will be marked as silenced, regardless of the originating
+ entities subscriptions.
+ - Specific entity can also be targeted by taking advantage of per-entity
+ subscription (entity:<entity_name>).
+ - This parameter is required if the I(check) parameter is absent.
+ type: str
+ check:
+ description:
+ - The name of the check the entry should match.
+ - If left empty a silencing entry will contain an asterisk in the check
+ position. This indicates that any event where the originating entities
+ subscriptions match the subscription specified in the entry will be
+ marked as silenced, regardless of the check name.
+ - This parameter is required if the I(subscription) parameter is absent.
+ type: str
+ begin:
+ description:
+ - UNIX time at which silence entry goes into effect.
+ type: int
+ expire:
+ description:
+ - Number of seconds until the silence expires.
+ type: int
+ expire_on_resolve:
+ description:
+ - If the entry should be deleted when a check begins return OK status (resolves).
+ type: bool
+ reason:
+ description:
+ - Reason for silencing.
+ type: str
+'''
+
+EXAMPLES = '''
+- name: Silence a specific check
+ sensu.sensu_go.silence:
+ subscription: proxy
+ check: check-disk
+
+- name: Silence specific check regardless of the originating entities subscription
+ sensu.sensu_go.silence:
+ check: check-cpu
+
+- name: Silence all checks on a specific entity
+ sensu.sensu_go.silence:
+ subscription: entity:important-entity
+ expire: 120
+ reason: rebooting the world
+
+- name: Delete a silencing entry
+ sensu.sensu_go.silence:
+ subscription: entity:important-entity
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu silence.
+ returned: success
+ type: dict
+ sample:
+ metadata:
+ annotations: null
+ labels: null
+ name: entity:i-424242:*
+ namespace: default
+ begin: 1542671205
+ check: null
+ creator: admin
+ expire: -1
+ expire_on_resolve: false
+ reason: null
+ subscription: entity:i-424242
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ required_one_of = [
+ ['subscription', 'check']
+ ]
+ module = AnsibleModule(
+ supports_check_mode=True,
+ required_one_of=required_one_of,
+ argument_spec=dict(
+ arguments.get_spec(
+ 'auth', 'state', 'labels', 'annotations', 'namespace',
+ ),
+ subscription=dict(),
+ check=dict(),
+ begin=dict(
+ type='int',
+ ),
+ expire=dict(
+ type='int',
+ ),
+ expire_on_resolve=dict(
+ type='bool'
+ ),
+ reason=dict()
+ ),
+ )
+ name = '{0}:{1}'.format(module.params['subscription'] or '*', module.params['check'] or '*')
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ module.params['namespace'], 'silenced', name,
+ )
+ # We add name parameter because it is actually required and must match the name that is
+ # autogenerated on the API
+ module.params['name'] = name
+ payload = arguments.get_mutation_payload(
+ module.params, 'subscription', 'check', 'begin', 'expire', 'expire_on_resolve', 'reason'
+ )
+ try:
+ changed, silence = utils.sync(
+ module.params['state'], client, path, payload, module.check_mode,
+ )
+ module.exit_json(changed=changed, object=silence)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/silence_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/silence_info.py
new file mode 100644
index 00000000..68769902
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/silence_info.py
@@ -0,0 +1,112 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: silence_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Manca Bizjak (@mancabizjak)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu silence entries
+description:
+ - Retrieve information about Sensu silences.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/silencing/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.namespace
+seealso:
+ - module: sensu.sensu_go.silence
+options:
+ subscription:
+ description:
+ - The name of the subscription the entry should match. If left empty a silencing entry will
+ contain an asterisk in the subscription position.
+ type: str
+ check:
+ description:
+ - The name of the check the entry should match. If left empty a silencing entry will contain an
+ asterisk in the check position.
+ type: str
+'''
+
+EXAMPLES = '''
+- name: List all Sensu silence entries
+ sensu.sensu_go.silence_info:
+ register: result
+
+- name: Fetch a specific silence with name proxy:awesome_check
+ sensu.sensu_go.silence_info:
+ subscription: proxy
+ check: awesome_check
+ register: result
+'''
+
+RETURN = '''
+objects:
+ description: List of Sensu silence entries.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - metadata:
+ annotations: null
+ labels: null
+ name: entity:i-424242:*
+ namespace: default
+ begin: 1542671205
+ check: null
+ creator: admin
+ expire: -1
+ expire_on_resolve: false
+ reason: null
+ subscription: entity:i-424242
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec('auth', 'namespace'),
+ subscription=dict(),
+ check=dict(),
+ ),
+ )
+
+ name = '{0}:{1}'.format(module.params['subscription'] or '*', module.params['check'] or '*')
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(
+ module.params["namespace"], "silenced", None if name == "*:*" else name,
+ )
+
+ try:
+ silences = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=silences)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/socket_handler.py b/ansible_collections/sensu/sensu_go/plugins/modules/socket_handler.py
new file mode 100644
index 00000000..ac42d27c
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/socket_handler.py
@@ -0,0 +1,160 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: socket_handler
+author:
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu TCP/UDP handler
+description:
+ - Create, update or delete Sensu socket handler.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/handlers/#tcp-udp-handlers).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+ - sensu.sensu_go.namespace
+ - sensu.sensu_go.state
+ - sensu.sensu_go.labels
+ - sensu.sensu_go.annotations
+seealso:
+ - module: sensu.sensu_go.handler_info
+ - module: sensu.sensu_go.pipe_handler
+ - module: sensu.sensu_go.handler_set
+options:
+ type:
+ description:
+ - The handler type.
+ - Required if I(state) is C(present).
+ choices:
+ - tcp
+ - udp
+ type: str
+ filters:
+ description:
+ - List of filters to use when determining whether to pass the check result to this handler.
+ type: list
+ elements: str
+ mutator:
+ description:
+ - Mutator to call for transforming the check result before passing it to this handler.
+ type: str
+ timeout:
+ description:
+ - Timeout for handler execution.
+ type: int
+ host:
+ description:
+ - The socket host address (IP or hostname) to connect to.
+ - Required if I(state) is C(present).
+ type: str
+ port:
+ description:
+ - The socket port to connect to.
+ - Required if I(state) is C(present).
+ type: int
+'''
+
+EXAMPLES = '''
+- name: TCP handler
+ sensu.sensu_go.socket_handler:
+ name: tcp_handler
+ type: tcp
+ host: 10.0.1.99
+ port: 4444
+
+- name: UDP handler
+ sensu.sensu_go.socket_handler:
+ name: udp_handler
+ type: udp
+ host: 10.0.1.99
+ port: 4444
+
+- name: Delete a handler
+ sensu.sensu_go.socket_handler:
+ name: udp_handler
+ state: absent
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu socket handler.
+ returned: success
+ type: dict
+ sample:
+ - metadata:
+ name: udp_handler
+ namespace: default
+ socket:
+ host: 10.0.1.99
+ port: 4444
+ type: udp
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ required_if = [
+ ('state', 'present', ['type', 'host', 'port'])
+ ]
+ module = AnsibleModule(
+ supports_check_mode=True,
+ required_if=required_if,
+ argument_spec=dict(
+ arguments.get_spec(
+ "auth", "name", "state", "labels", "annotations", "namespace",
+ ),
+ type=dict(choices=['tcp', 'udp']),
+ filters=dict(
+ type='list', elements='str',
+ ),
+ mutator=dict(),
+ timeout=dict(
+ type='int'
+ ),
+ host=dict(),
+ port=dict(
+ type='int'
+ )
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(
+ module.params['namespace'], 'handlers', module.params['name'],
+ )
+ payload = arguments.get_mutation_payload(
+ module.params, 'type', 'filters', 'mutator', 'timeout'
+ )
+ payload['socket'] = dict(host=module.params['host'], port=module.params['port'])
+
+ try:
+ changed, handler = utils.sync(
+ module.params['state'], client, path, payload, module.check_mode,
+ )
+ module.exit_json(changed=changed, object=handler)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/tessen.py b/ansible_collections/sensu/sensu_go/plugins/modules/tessen.py
new file mode 100644
index 00000000..ba18f518
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/tessen.py
@@ -0,0 +1,108 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: tessen
+author:
+ - Paul Arthur (@flowerysong)
+ - Manca Bizjak (@mancabizjak)
+ - Aljaz Kosir (@aljazkosir)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu's Tessen configuration
+description:
+ - Enable or disable Tessen service.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/tessen/).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+options:
+ state:
+ description:
+ - Enable or disable sending anonymized data to Sensu Inc.
+ choices: [ enabled, disabled ]
+ type: str
+ required: True
+'''
+
+EXAMPLES = '''
+- name: Disable Tessen
+ sensu.sensu_go.tessen:
+ state: disabled
+ register: result
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu tessen.
+ returned: success
+ type: dict
+ sample:
+ opt_out: false
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def get(client, path):
+ resp = client.get(path)
+ if resp.status != 200:
+ raise errors.SyncError(
+ "GET {0} failed with status {1}: {2}".format(path, resp.status, resp.data))
+ return resp.json
+
+
+def sync(client, path, payload, check_mode):
+ remote_object = get(client, path)
+
+ if utils.do_differ(remote_object, payload):
+ if check_mode:
+ return True, payload
+ utils.put(client, path, payload)
+ return True, get(client, path)
+
+ return False, remote_object
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec('auth'),
+ state=dict(
+ choices=['enabled', 'disabled'],
+ required=True,
+ )
+ )
+ )
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(None, 'tessen')
+ payload = dict(
+ opt_out=module.params['state'] == 'disabled'
+ )
+
+ try:
+ changed, tessen = sync(client, path, payload, module.check_mode)
+ module.exit_json(changed=changed, object=tessen)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/user.py b/ansible_collections/sensu/sensu_go/plugins/modules/user.py
new file mode 100644
index 00000000..4ef15586
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/user.py
@@ -0,0 +1,326 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: user
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Tadej Borovsak (@tadeboro)
+short_description: Manage Sensu users
+description:
+ - Create, update, activate or deactivate Sensu user.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#users).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.name
+requirements:
+ - bcrypt (when managing Sensu Go 5.21.0 or newer)
+seealso:
+ - module: sensu.sensu_go.user_info
+options:
+ state:
+ description:
+ - Desired state of the user.
+ - Users cannot actually be deleted, only deactivated.
+ type: str
+ choices: [ enabled, disabled ]
+ default: enabled
+ password:
+ description:
+ - Password for the user.
+ - Required if user with a desired name does not exist yet on the backend
+ and I(password_hash) is not set.
+ - If both I(password) and I(password_hash) are set, I(password_hash) is
+ ignored and calculated from the I(password) if required.
+ type: str
+ password_hash:
+ description:
+ - Bcrypt password hash for the user.
+ - Use C(sensuctl user hash-password PASSWORD) to generate a hash.
+ - Required if user with a desired name does not exist yet on the backend
+ and I(password) is not set.
+ - If both I(password) and I(password_hash) are set, I(password_hash) is
+ ignored and calculated from the I(password) if required.
+ - Sensu Go < 5.21.0 does not support creating/updating users using
+ hashed passwords. Use I(password) parameter if you need to manage such
+ Sensu Go installations.
+ - At the moment, change detection does not work properly when using
+ password hashes because the Sensu Go backend does not expose enough
+ information via its API.
+ type: str
+ version_added: 1.8.0
+ groups:
+ description:
+ - List of groups user belongs to.
+ type: list
+ elements: str
+'''
+
+EXAMPLES = '''
+- name: Create a user
+ sensu.sensu_go.user:
+ auth:
+ url: http://localhost:8080
+ name: awesome_username
+ password: hidden_password?
+ groups:
+ - dev
+ - prod
+
+- name: Use pre-hashed password
+ sensu.sensu_go.user:
+ auth:
+ url: http://localhost:8080
+ name: awesome_username
+ password_hash: $5f$14$.brXRviMZpbaleSq9kjoUuwm67V/s4IziOLGHjEqxJbzPsreQAyNm
+
+- name: Deactivate a user
+ sensu.sensu_go.user:
+ name: awesome_username
+ state: disabled
+'''
+
+RETURN = '''
+object:
+ description: Object representing Sensu user.
+ returned: success
+ type: dict
+ sample:
+ disabled: false
+ groups:
+ - ops
+ - dev
+ password: USER_PASSWORD
+ password_hash: $5f$14$.brXRviMZpbaleSq9kjoUuwm67V/s4IziOLGHjEqxJbzPsreQAyNm
+ username: alice
+'''
+
+import traceback
+
+from ansible.module_utils.basic import AnsibleModule, missing_required_lib
+
+from ..module_utils import arguments, errors, utils
+
+try:
+ import bcrypt
+ HAS_BCRYPT = True
+ BCRYPT_IMPORT_ERROR = None
+except ImportError:
+ HAS_BCRYPT = False
+ BCRYPT_IMPORT_ERROR = traceback.format_exc()
+
+
+def _simulate_backend_response(payload):
+ # Backend does not return back any password-related information for now.
+ masked_keys = ('password', 'password_hash')
+ return dict(
+ (k, v) for k, v in payload.items() if k not in masked_keys
+ )
+
+
+def update_password(client, path, username, password, check_mode):
+ # Hit the auth testing API and try to validate the credentials. If the API
+ # says they are invalid, we need to update them.
+ if client.validate_auth_data(username, password):
+ return False
+
+ if not check_mode:
+ if client.version < "5.21.0":
+ utils.put(client, path + '/password', dict(
+ username=username, password=password,
+ ))
+ else:
+ hash = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
+ utils.put(client, path + '/reset_password', dict(
+ username=username, password_hash=hash.decode('ascii'),
+ ))
+
+ return True
+
+
+def update_password_hash(client, path, username, password_hash, check_mode):
+ # Some older Sensu Go versions do not have support for password hashes.
+ if client.version < "5.21.0":
+ raise errors.SensuError(
+ "Sensu Go < 5.21.0 does not support password hashes"
+ )
+
+ # Insert change detection here once we can receive password hash from the
+ # backend. Up until then, we always update passwords.
+
+ if not check_mode:
+ utils.put(client, path + '/reset_password', dict(
+ username=username, password_hash=password_hash,
+ ))
+
+ return True
+
+
+def update_groups(client, path, old_groups, new_groups, check_mode):
+ to_delete = set(old_groups).difference(new_groups)
+ to_add = set(new_groups).difference(old_groups)
+
+ if not check_mode:
+ # Next few lines are far from atomic, which means that we can leave a
+ # user in any of the intermediate states, but this is the best we can
+ # do given the API limitations.
+ for g in to_add:
+ utils.put(client, path + '/groups/' + g, None)
+ for g in to_delete:
+ utils.delete(client, path + '/groups/' + g)
+
+ return len(to_delete) + len(to_add) > 0
+
+
+def update_state(client, path, old_disabled, new_disabled, check_mode):
+ changed = old_disabled != new_disabled
+
+ if not check_mode and changed:
+ if new_disabled: # `state: disabled` input parameter
+ utils.delete(client, path)
+ else: # `state: enabled` input parameter
+ utils.put(client, path + '/reinstate', None)
+
+ return changed
+
+
+def sync(remote_object, client, path, payload, check_mode):
+ # Create new user (either enabled or disabled)
+ if remote_object is None:
+ if check_mode:
+ return True, _simulate_backend_response(payload)
+ utils.put(client, path, payload)
+ return True, utils.get(client, path)
+
+ # Update existing user. We do this on a field-by-field basis because the
+ # upsteam API for updating users requires a password field to be set. Of
+ # course, we do not want to force users to specify an existing password
+ # just for the sake of updating the group membership, so this is why we
+ # use field-specific API endpoints to update the user data.
+
+ changed = False
+
+ # We only use password hash if we do not have a password. In practice,
+ # this means that users should not set both password and password_hash. We
+ # do not enforce this by making those two parameters mutually exclusive
+ # because in the future (2.0.0 version of collection), we intend to move
+ # password hashing into action plugin and supply both the password and its
+ # hash. Why? Because installing bcrypt on control node is way friendlier
+ # compared to installing bcrypt on every host that runs our user module.
+ #
+ # It is true that most of the time, control node == target node in our
+ # cases, but not always.
+ if 'password' in payload:
+ changed = update_password(
+ client, path, payload['username'], payload['password'],
+ check_mode,
+ ) or changed
+ elif 'password_hash' in payload:
+ changed = update_password_hash(
+ client, path, payload['username'], payload['password_hash'],
+ check_mode,
+ ) or changed
+
+ if 'groups' in payload:
+ changed = update_groups(
+ client, path, remote_object.get('groups') or [],
+ payload['groups'], check_mode,
+ ) or changed
+
+ if 'disabled' in payload:
+ changed = update_state(
+ client, path, remote_object['disabled'], payload['disabled'],
+ check_mode,
+ ) or changed
+
+ if check_mode:
+ # Backend does not return back passwords, so we should follow the
+ # example set by the backend API.
+ return changed, dict(
+ remote_object, **_simulate_backend_response(payload)
+ )
+
+ return changed, utils.get(client, path)
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth", "name"),
+ state=dict(
+ default='enabled',
+ choices=['enabled', 'disabled'],
+ ),
+ password=dict(
+ no_log=True
+ ),
+ password_hash=dict(
+ no_log=False, # Showing hashes is perfectly OK
+ ),
+ groups=dict(
+ type='list', elements='str',
+ )
+ ),
+ )
+
+ client = arguments.get_sensu_client(module.params['auth'])
+ path = utils.build_core_v2_path(None, 'users', module.params['name'])
+
+ try:
+ if not HAS_BCRYPT and client.version >= "5.21.0":
+ module.fail_json(
+ msg=missing_required_lib('bcrypt'),
+ exception=BCRYPT_IMPORT_ERROR,
+ )
+ except errors.SensuError as e:
+ module.fail_json(msg=str(e))
+
+ try:
+ remote_object = utils.get(client, path)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ if (
+ remote_object is None
+ and module.params['password'] is None
+ and module.params['password_hash'] is None
+ ):
+ module.fail_json(
+ msg='Cannot create new user without a password or a hash'
+ )
+
+ payload = arguments.get_spec_payload(
+ module.params, 'password', 'password_hash', 'groups',
+ )
+ payload['username'] = module.params['name']
+ payload['disabled'] = module.params['state'] == 'disabled'
+
+ try:
+ changed, user = sync(
+ remote_object, client, path, payload, module.check_mode
+ )
+ module.exit_json(changed=changed, object=user)
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/sensu/sensu_go/plugins/modules/user_info.py b/ansible_collections/sensu/sensu_go/plugins/modules/user_info.py
new file mode 100644
index 00000000..ad9eda8f
--- /dev/null
+++ b/ansible_collections/sensu/sensu_go/plugins/modules/user_info.py
@@ -0,0 +1,90 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Paul Arthur <paul.arthur@flowerysong.com>
+# Copyright: (c) 2019, XLAB Steampunk <steampunk@xlab.si>
+#
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+ANSIBLE_METADATA = {
+ "metadata_version": "1.1",
+ "status": ["stableinterface"],
+ "supported_by": "certified",
+}
+
+DOCUMENTATION = '''
+module: user_info
+author:
+ - Paul Arthur (@flowerysong)
+ - Aljaz Kosir (@aljazkosir)
+ - Miha Plesko (@miha-plesko)
+ - Tadej Borovsak (@tadeboro)
+short_description: List Sensu users
+description:
+ - Retrieve information about Sensu users.
+ - For more information, refer to the Sensu documentation at
+ U(https://docs.sensu.io/sensu-go/latest/reference/rbac/#users).
+version_added: 1.0.0
+extends_documentation_fragment:
+ - sensu.sensu_go.requirements
+ - sensu.sensu_go.auth
+ - sensu.sensu_go.info
+seealso:
+ - module: sensu.sensu_go.user
+'''
+
+EXAMPLES = '''
+- name: List Sensu users
+ sensu.sensu_go.user_info:
+ register: result
+
+- name: Retrieve a single Sensu user
+ sensu.sensu_go.user_info:
+ name: my-user
+ register: result
+'''
+
+RETURN = '''
+objects:
+ description: List of Sensu users.
+ returned: success
+ type: list
+ elements: dict
+ sample:
+ - disabled: false
+ groups:
+ - ops
+ - dev
+ password: USER_PASSWORD
+ password_hash: $5f$14$.brXRviMZpbaleSq9kjoUuwm67V/s4IziOLGHjEqxJbzPsreQAyNm
+ username: alice
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ..module_utils import arguments, errors, utils
+
+
+def main():
+ module = AnsibleModule(
+ supports_check_mode=True,
+ argument_spec=dict(
+ arguments.get_spec("auth"),
+ name=dict(), # Name is not required in info modules.
+ ),
+ )
+ client = arguments.get_sensu_client(module.params["auth"])
+ path = utils.build_core_v2_path(None, "users", module.params["name"])
+
+ try:
+ users = utils.prepare_result_list(utils.get(client, path))
+ except errors.Error as e:
+ module.fail_json(msg=str(e))
+
+ module.exit_json(changed=False, objects=users)
+
+
+if __name__ == '__main__':
+ main()