From 08fc5bcea12bf63ff02cf72520b930502b359901 Mon Sep 17 00:00:00 2001 From: Mohammed Naser Date: Wed, 31 Jul 2019 14:44:39 -0400 Subject: [PATCH] initial commit Change-Id: I87aa6de6ab5c8311ad76396cf4b35396f88d8735 --- .gitignore | 2 + doc/requirements.txt | 3 + doc/source/conf.py | 3 + doc/source/index.rst | 67 ++++ playbooks/ceph-install.yml | 42 +++ playbooks/common-tasks/configure-sudo.yml | 20 ++ playbooks/common-tasks/install-plugins.yml | 21 ++ playbooks/common-tasks/setup-checks.yml | 24 ++ playbooks/galera-install.yml | 66 ++++ playbooks/haproxy-install.yml | 41 +++ playbooks/library/rabbitmq_user.py | 321 ++++++++++++++++++ playbooks/memcached-install.yml | 36 ++ playbooks/openstack-hosts-setup.yml | 53 +++ playbooks/rabbitmq-install.yml | 83 +++++ .../roles/sensu_client/defaults/main.yml | 20 ++ playbooks/roles/sensu_client/files/sudoers | 2 + playbooks/roles/sensu_client/meta/main.yml | 25 ++ playbooks/roles/sensu_client/tasks/main.yml | 42 +++ .../sensu_client/templates/rabbitmq.json.j2 | 7 + .../roles/sensu_common/handlers/main.yml | 19 ++ playbooks/setup-everything.yml | 18 + playbooks/setup-hosts.yml | 16 + playbooks/setup-infrastructure.yml | 20 ++ playbooks/templates/my.cnf.j2 | 7 + playbooks/templates/rabbitmq.ini.j2 | 3 + test-requirements.txt | 1 + tox.ini | 19 ++ zuul.d/project.yaml | 27 ++ 28 files changed, 1008 insertions(+) create mode 100644 .gitignore create mode 100644 doc/requirements.txt create mode 100644 doc/source/conf.py create mode 100644 doc/source/index.rst create mode 100644 playbooks/ceph-install.yml create mode 100644 playbooks/common-tasks/configure-sudo.yml create mode 100644 playbooks/common-tasks/install-plugins.yml create mode 100644 playbooks/common-tasks/setup-checks.yml create mode 100644 playbooks/galera-install.yml create mode 100644 playbooks/haproxy-install.yml create mode 100644 playbooks/library/rabbitmq_user.py create mode 100644 playbooks/memcached-install.yml create mode 100644 playbooks/openstack-hosts-setup.yml create mode 100644 playbooks/rabbitmq-install.yml create mode 100644 playbooks/roles/sensu_client/defaults/main.yml create mode 100644 playbooks/roles/sensu_client/files/sudoers create mode 100644 playbooks/roles/sensu_client/meta/main.yml create mode 100644 playbooks/roles/sensu_client/tasks/main.yml create mode 100644 playbooks/roles/sensu_client/templates/rabbitmq.json.j2 create mode 100644 playbooks/roles/sensu_common/handlers/main.yml create mode 100644 playbooks/setup-everything.yml create mode 100644 playbooks/setup-hosts.yml create mode 100644 playbooks/setup-infrastructure.yml create mode 100644 playbooks/templates/my.cnf.j2 create mode 100644 playbooks/templates/rabbitmq.ini.j2 create mode 100644 test-requirements.txt create mode 100644 tox.ini create mode 100644 zuul.d/project.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..efe3bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.tox +doc/build \ No newline at end of file diff --git a/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 0000000..8579aa6 --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1,3 @@ +doc8==0.8.0 +reno==2.11.3 +Sphinx==2.1.2 diff --git a/doc/source/conf.py b/doc/source/conf.py new file mode 100644 index 0000000..9a4a2ab --- /dev/null +++ b/doc/source/conf.py @@ -0,0 +1,3 @@ +project = 'openstack-monitoring' +copyright = '2019, VEXXHOST, Inc.' +author = 'VEXXHOST, Inc.' \ No newline at end of file diff --git a/doc/source/index.rst b/doc/source/index.rst new file mode 100644 index 0000000..55bdc48 --- /dev/null +++ b/doc/source/index.rst @@ -0,0 +1,67 @@ +OpenStack-Ansible Monitoring +============================ +``openstack-monitoring`` is a repository that contains a set of playbooks which +deploy ``sensu-client``, configure it to point towards the RabbitMQ cluster +that hosts your ``sensu-server`` and sets up monitoring for an OpenStack +cloud deployed using OpenStack-Ansible. + + +Usage +----- +The playbooks are quite straightforward to use. You'll need to clone them +locally on your OpenStack-Ansible deploy node as they rely on the inventory +structure used by OpenStack-Ansible to work. + +#. Clone the latest version of the ``openstack-monitoring`` Git repository in + the ``/opt/openstack-monitoring`` directory: + + .. code:: + + git clone https://opendev.org/vexxhost/openstack-monitoring /opt/openstack-monitoring + + +#. Add the following variables inside your ``user_variables.yml`` file in order + for the playbooks to ensure that they point towards the RabbitMQ which your + ``sensu-server`` is configured to listen to. + + .. code:: + + sensu_rabbitmq_host: + sensu_rabbitmq_user: + +#. Add the following variables inside your ``user_secrets.yml`` file in order + for the playbooks to authenticate to your RabbitMQ server (for Sensu) and + for the monitoring accounts which will be created by the playbooks. + + .. code:: + + sensu_rabbitmq_password: + sensu_monitoring_galera_password: + sensu_monitoring_rabbitmq_password: + + .. note:: + + All of the variables that start with ``sensu_monitoring`` are used for the + monitoring infrastructure. The playbooks will create a MySQL user account + and RabbitMQ user account which will be used for monitoring. + +#. You can choose to run individual playbooks from within the ``playbooks`` + folder or you can opt to run all the playbooks right away by using + the ``setup-everything.yml`` playbook. + + .. code:: + + openstack-ansible setup-everything.yml + + The playbooks are named after the same ones inside OpenStack-Ansible so + it should be very easy to find which ones that you need to run specifically + if you need that. + + +Contributing +------------ +This project is hosted inside OpenDev, so it uses Gerrit for code review for +changes. You can read more about how the process works by checking out +the `Learn the Gerrit Workflow in the Sandbox`_ article. + +.. _`Learn the Gerrit Workflow in the Sandbox`: https://docs.openstack.org/infra/manual/sandbox.html diff --git a/playbooks/ceph-install.yml b/playbooks/ceph-install.yml new file mode 100644 index 0000000..82d43fd --- /dev/null +++ b/playbooks/ceph-install.yml @@ -0,0 +1,42 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Monitor ceph mons + hosts: ceph-mon + gather_facts: "{{ osa_gather_facts | default(True) }}" + user: root + roles: + - role: sensu_common + tasks: + - import_tasks: common-tasks/install-plugins.yml + vars: + sensu_plugins: ['sensu-plugins-ceph'] + + - import_tasks: common-tasks/configure-sudo.yml + vars: + sensu_commands: + - /opt/sensu/embedded/bin/check-ceph.rb -d + + - import_tasks: common-tasks/setup-checks.yml + vars: + sensu_checks: + - name: ceph + command: sudo check-ceph.rb -d + vars: + sensu_service: ceph + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - ceph + - ceph-mon \ No newline at end of file diff --git a/playbooks/common-tasks/configure-sudo.yml b/playbooks/common-tasks/configure-sudo.yml new file mode 100644 index 0000000..6464192 --- /dev/null +++ b/playbooks/common-tasks/configure-sudo.yml @@ -0,0 +1,20 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Allow sensu to sudo + copy: + content: "sensu ALL=(ALL) NOPASSWD: {{ sensu_commands|join('\n') }}\n" + dest: "/etc/sudoers.d/sensu_{{ sensu_service }}" + mode: 0440 \ No newline at end of file diff --git a/playbooks/common-tasks/install-plugins.yml b/playbooks/common-tasks/install-plugins.yml new file mode 100644 index 0000000..349a0e4 --- /dev/null +++ b/playbooks/common-tasks/install-plugins.yml @@ -0,0 +1,21 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Install Sensu plugins + gem: + name: "{{ item }}" + executable: /opt/sensu/embedded/bin/gem + user_install: false + with_items: "{{ sensu_plugins }}" \ No newline at end of file diff --git a/playbooks/common-tasks/setup-checks.yml b/playbooks/common-tasks/setup-checks.yml new file mode 100644 index 0000000..9f5425e --- /dev/null +++ b/playbooks/common-tasks/setup-checks.yml @@ -0,0 +1,24 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Add checks + sensu_check: + name: "{{ item.name }}" + command: "{{ item.command }}" + interval: "{{ item.interval | default(60) }}" + standalone: true + path: "/etc/sensu/conf.d/{{ sensu_service }}.json" + notify: Restart sensu-client + with_items: "{{ sensu_checks }}" \ No newline at end of file diff --git a/playbooks/galera-install.yml b/playbooks/galera-install.yml new file mode 100644 index 0000000..cf8d904 --- /dev/null +++ b/playbooks/galera-install.yml @@ -0,0 +1,66 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Monitor galera + hosts: galera_all + gather_facts: "{{ osa_gather_facts | default(True) }}" + user: root + roles: + - role: sensu_common + tasks: + - name: Install missing libraries + yum: + name: + - MariaDB-devel + - MariaDB-shared + state: present + + - import_tasks: common-tasks/install-plugins.yml + vars: + sensu_plugins: ['sensu-plugins-mysql', 'sensu-plugins-percona'] + + - name: Create monitoring user + run_once: true + mysql_user: + name: sensu + password: "{{ sensu_monitoring_galera_password }}" + host: "%" + priv: 'test.*:ALL/*.*:PROCESS' + + - name: Create .my.cnf file + template: + src: my.cnf.j2 + dest: /opt/sensu/.my.cnf + + - import_tasks: common-tasks/setup-checks.yml + vars: + sensu_checks: + - name: mysql-alive + command: "check-mysql-alive.rb -h{{ galera_wsrep_address }} -i /opt/sensu/.my.cnf" + - name: mysql-status + command: "check-mysql-status.rb -h{{ galera_wsrep_address }} -i /opt/sensu/.my.cnf" + - name: mysql-innodb-lock + command: "check-mysql-innodb-lock.rb -h{{ galera_wsrep_address }} -i /opt/sensu/.my.cnf" + - name: mysql-connections + command: "check-mysql-connections.rb -h{{ galera_wsrep_address }} -i /opt/sensu/.my.cnf -a -w 80 -c 90" + - name: percona-cluster-size + command: "check-percona-cluster-size.rb -i /opt/sensu/.my.cnf -e {{ groups['galera_all'] | length }}" + vars: + galera_server_id: "{{ inventory_hostname | string_2_int }}" + galera_wsrep_node_name: "{{ container_name | default(inventory_hostname) }}" + sensu_service: galera + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - galera \ No newline at end of file diff --git a/playbooks/haproxy-install.yml b/playbooks/haproxy-install.yml new file mode 100644 index 0000000..ec90c4d --- /dev/null +++ b/playbooks/haproxy-install.yml @@ -0,0 +1,41 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Monitor haproxy + hosts: haproxy + gather_facts: "{{ osa_gather_facts | default(True) }}" + user: root + roles: + - role: sensu_common + tasks: + - import_tasks: common-tasks/install-plugins.yml + vars: + sensu_plugins: ['sensu-plugins-haproxy'] + + - import_tasks: common-tasks/configure-sudo.yml + vars: + sensu_commands: + - /opt/sensu/embedded/bin/check-haproxy.rb -S /var/run/haproxy.stat -c 100 -b 100 -B 100 -A + + - import_tasks: common-tasks/setup-checks.yml + vars: + sensu_checks: + - name: haproxy + command: sudo check-haproxy.rb -S /var/run/haproxy.stat -c 100 -b 100 -B 100 -A + vars: + sensu_service: haproxy + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - haproxy \ No newline at end of file diff --git a/playbooks/library/rabbitmq_user.py b/playbooks/library/rabbitmq_user.py new file mode 100644 index 0000000..f4e0436 --- /dev/null +++ b/playbooks/library/rabbitmq_user.py @@ -0,0 +1,321 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2013, Chatham Financial +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: rabbitmq_user +short_description: Adds or removes users to RabbitMQ +description: + - Add or remove users to RabbitMQ and assign permissions +version_added: "1.1" +author: '"Chris Hoffman (@chrishoffman)"' +options: + user: + description: + - Name of user to add + required: true + aliases: [username, name] + password: + description: + - Password of user to add. + - To change the password of an existing user, you must also specify + C(update_password=always). + tags: + description: + - User tags specified as comma delimited + permissions: + description: + - a list of dicts, each dict contains vhost, configure_priv, write_priv, and read_priv, + and represents a permission rule for that vhost. + - This option should be preferable when you care about all permissions of the user. + - You should use vhost, configure_priv, write_priv, and read_priv options instead + if you care about permissions for just some vhosts. + default: [] + vhost: + description: + - vhost to apply access privileges. + - This option will be ignored when permissions option is used. + default: / + node: + description: + - erlang node name of the rabbit we wish to configure + default: rabbit + version_added: "1.2" + configure_priv: + description: + - Regular expression to restrict configure actions on a resource + for the specified vhost. + - By default all actions are restricted. + - This option will be ignored when permissions option is used. + default: ^$ + write_priv: + description: + - Regular expression to restrict configure actions on a resource + for the specified vhost. + - By default all actions are restricted. + - This option will be ignored when permissions option is used. + default: ^$ + read_priv: + description: + - Regular expression to restrict configure actions on a resource + for the specified vhost. + - By default all actions are restricted. + - This option will be ignored when permissions option is used. + default: ^$ + force: + description: + - Deletes and recreates the user. + type: bool + default: 'no' + state: + description: + - Specify if user is to be added or removed + default: present + choices: [present, absent] + update_password: + description: + - C(on_create) will only set the password for newly created users. C(always) will update passwords if they differ. + required: false + default: on_create + choices: [ on_create, always ] + version_added: "2.6" +''' + +EXAMPLES = ''' +# Add user to server and assign full access control on / vhost. +# The user might have permission rules for other vhost but you don't care. +- rabbitmq_user: + user: joe + password: changeme + vhost: / + configure_priv: .* + read_priv: .* + write_priv: .* + state: present + +# Add user to server and assign full access control on / vhost. +# The user doesn't have permission rules for other vhosts +- rabbitmq_user: + user: joe + password: changeme + permissions: + - vhost: / + configure_priv: .* + read_priv: .* + write_priv: .* + state: present +''' + +from ansible.module_utils.basic import AnsibleModule + + +class RabbitMqUser(object): + def __init__(self, module, username, password, tags, permissions, + node, bulk_permissions=False): + self.module = module + self.username = username + self.password = password + self.node = node + if not tags: + self.tags = list() + else: + self.tags = tags.split(',') + + self.permissions = permissions + self.bulk_permissions = bulk_permissions + + self._tags = None + self._permissions = [] + self._rabbitmqctl = module.get_bin_path('rabbitmqctl', True) + + def _exec(self, args, run_in_check_mode=False): + if not self.module.check_mode or run_in_check_mode: + cmd = [self._rabbitmqctl, '-q'] + if self.node is not None: + cmd.extend(['-n', self.node]) + rc, out, err = self.module.run_command(cmd + args, check_rc=True) + return out.splitlines() + return list() + + def get(self): + users = self._exec(['list_users'], True) + + for user_tag in users: + if '\t' not in user_tag: + continue + + user, tags = user_tag.split('\t') + + if user == self.username: + for c in ['[', ']', ' ']: + tags = tags.replace(c, '') + + if tags != '': + self._tags = tags.split(',') + else: + self._tags = list() + + self._permissions = self._get_permissions() + return True + return False + + def _get_permissions(self): + perms_out = [perm for perm in self._exec(['list_user_permissions', self.username], True) if perm.strip()] + + # NOTE(mnaser): Fix for RabbitMQ >= 3.7.9 + if perms_out[0] == 'vhost\tconfigure\twrite\tread': + perms_out.pop(0) + + perms_list = list() + for perm in perms_out: + vhost, configure_priv, write_priv, read_priv = perm.split('\t') + if not self.bulk_permissions: + if vhost == self.permissions[0]['vhost']: + perms_list.append(dict(vhost=vhost, configure_priv=configure_priv, + write_priv=write_priv, read_priv=read_priv)) + break + else: + perms_list.append(dict(vhost=vhost, configure_priv=configure_priv, + write_priv=write_priv, read_priv=read_priv)) + return perms_list + + def check_password(self): + return self._exec(['authenticate_user', self.username, self.password], True) + + def add(self): + if self.password is not None: + self._exec(['add_user', self.username, self.password]) + else: + self._exec(['add_user', self.username, '']) + self._exec(['clear_password', self.username]) + + def delete(self): + self._exec(['delete_user', self.username]) + + def change_password(self): + if self.password is not None: + self._exec(['change_password', self.username, self.password]) + else: + self._exec(['clear_password', self.username]) + + def set_tags(self): + self._exec(['set_user_tags', self.username] + self.tags) + + def set_permissions(self): + for permission in self._permissions: + if permission not in self.permissions: + cmd = ['clear_permissions', '-p'] + cmd.append(permission['vhost']) + cmd.append(self.username) + self._exec(cmd) + for permission in self.permissions: + if permission not in self._permissions: + cmd = ['set_permissions', '-p'] + cmd.append(permission['vhost']) + cmd.append(self.username) + cmd.append(permission['configure_priv']) + cmd.append(permission['write_priv']) + cmd.append(permission['read_priv']) + self._exec(cmd) + + def has_tags_modifications(self): + return set(self.tags) != set(self._tags) + + def has_permissions_modifications(self): + return sorted(self._permissions) != sorted(self.permissions) + + +def main(): + arg_spec = dict( + user=dict(required=True, aliases=['username', 'name']), + password=dict(default=None, no_log=True), + tags=dict(default=None), + permissions=dict(default=list(), type='list'), + vhost=dict(default='/'), + configure_priv=dict(default='^$'), + write_priv=dict(default='^$'), + read_priv=dict(default='^$'), + force=dict(default='no', type='bool'), + state=dict(default='present', choices=['present', 'absent']), + node=dict(default=None), + update_password=dict(default='on_create', choices=['on_create', 'always']) + ) + module = AnsibleModule( + argument_spec=arg_spec, + supports_check_mode=True + ) + + username = module.params['user'] + password = module.params['password'] + tags = module.params['tags'] + permissions = module.params['permissions'] + vhost = module.params['vhost'] + configure_priv = module.params['configure_priv'] + write_priv = module.params['write_priv'] + read_priv = module.params['read_priv'] + force = module.params['force'] + state = module.params['state'] + node = module.params['node'] + update_password = module.params['update_password'] + + bulk_permissions = True + if not permissions: + perm = { + 'vhost': vhost, + 'configure_priv': configure_priv, + 'write_priv': write_priv, + 'read_priv': read_priv + } + permissions.append(perm) + bulk_permissions = False + + rabbitmq_user = RabbitMqUser(module, username, password, tags, permissions, + node, bulk_permissions=bulk_permissions) + + result = dict(changed=False, user=username, state=state) + + if rabbitmq_user.get(): + if state == 'absent': + rabbitmq_user.delete() + result['changed'] = True + else: + if force: + rabbitmq_user.delete() + rabbitmq_user.add() + rabbitmq_user.get() + result['changed'] = True + elif update_password == 'always': + if not rabbitmq_user.check_password(): + rabbitmq_user.change_password() + result['changed'] = True + + if rabbitmq_user.has_tags_modifications(): + rabbitmq_user.set_tags() + result['changed'] = True + + if rabbitmq_user.has_permissions_modifications(): + rabbitmq_user.set_permissions() + result['changed'] = True + elif state == 'present': + rabbitmq_user.add() + rabbitmq_user.set_tags() + rabbitmq_user.set_permissions() + result['changed'] = True + + module.exit_json(**result) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/playbooks/memcached-install.yml b/playbooks/memcached-install.yml new file mode 100644 index 0000000..5611fa2 --- /dev/null +++ b/playbooks/memcached-install.yml @@ -0,0 +1,36 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Monitor memcached + hosts: memcached + gather_facts: "{{ osa_gather_facts | default(True) }}" + user: root + roles: + - role: sensu_common + tasks: + - import_tasks: common-tasks/install-plugins.yml + vars: + sensu_plugins: ['sensu-plugins-memcached'] + + - import_tasks: common-tasks/setup-checks.yml + vars: + sensu_checks: + - name: memcached-stats + command: "check-memcached-stats.rb -h {{ memcached_listen }} -p {{ memcached_port }}" + vars: + sensu_service: memcached + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - memcached \ No newline at end of file diff --git a/playbooks/openstack-hosts-setup.yml b/playbooks/openstack-hosts-setup.yml new file mode 100644 index 0000000..6ab6de7 --- /dev/null +++ b/playbooks/openstack-hosts-setup.yml @@ -0,0 +1,53 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Basic host setup + hosts: "{{ openstack_host_group|default('hosts') }}" + gather_facts: "{{ osa_gather_facts | default(True) }}" + user: root + roles: + - role: "sensu_client" + vars: + sensu_service: host + tasks: + - import_tasks: common-tasks/install-plugins.yml + vars: + sensu_plugins: + - sensu-plugins-chrony + - sensu-plugins-cpu-checks + - sensu-plugins-disk-checks + - sensu-plugins-entropy-checks + - sensu-plugins-load-checks + + - import_tasks: common-tasks/configure-sudo.yml + vars: + sensu_command: /opt/sensu/embedded/bin/check-disk-usage.rb -x proc + + - import_tasks: common-tasks/setup-checks.yml + vars: + sensu_checks: + - name: chrony + command: check-chrony.rb + - name: cpu + command: check-cpu.rb + - name: disk-usage + command: sudo check-disk-usage.rb -x proc + - name: entropy + command: check-entropy.rb + - name: load + command: check-load.rb + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - openstack-hosts \ No newline at end of file diff --git a/playbooks/rabbitmq-install.yml b/playbooks/rabbitmq-install.yml new file mode 100644 index 0000000..c8a768f --- /dev/null +++ b/playbooks/rabbitmq-install.yml @@ -0,0 +1,83 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Monitor rabbitmq + hosts: "{{ rabbitmq_host_group | default('rabbitmq_all') }}" + gather_facts: "{{ osa_gather_facts | default(True) }}" + user: root + roles: + - role: sensu_common + tasks: + - import_tasks: common-tasks/install-plugins.yml + vars: + sensu_plugins: ['sensu-plugins-rabbitmq'] + + - name: Get list of all virtual hosts + changed_when: false + shell: rabbitmqctl -s list_vhosts + register: _rabbitmqctl_vhosts + tags: + - skip_ansible_lint + + # NOTE(mnaser): rabbitmq_user is currently broken when using newer + # versions of RabbitMQ. This is why it's vendored in + # these playbooks. + # + # see: https://github.com/ansible/ansible/issues/48890 + - name: Create monitoring user + run_once: true + rabbitmq_user: + user: sensu + password: "{{ sensu_monitoring_rabbitmq_password }}" + tags: monitoring + permissions: "{{ _rabbitmq_permissions }}" + vars: + _rabbitmq_permissions: |- + {% set permissions = [] %} + {% for vhost in _rabbitmqctl_vhosts.stdout_lines %} + {% set _ = permissions.append({ + 'vhost': vhost, + 'configure_priv': '.*', + 'read_priv': '.*', + 'write_priv': '.*' + }) %} + {% endfor %} + {{ permissions }} + + - name: Create auth file + template: + src: rabbitmq.ini.j2 + dest: /opt/sensu/rabbitmq.ini + + - import_tasks: common-tasks/setup-checks.yml + vars: + sensu_checks: + - name: rabbitmq-alive + command: "check-rabbitmq-alive.rb -w {{ rabbitmq_management_bind_address }} -i /opt/sensu/rabbitmq.ini" + - name: rabbitmq-amqp + command: "check-rabbitmq-amqp-alive.rb -w {{ rabbitmq_management_bind_address }} -i /opt/sensu/rabbitmq.ini" + - name: rabbitmq-cluster-health + command: "check-rabbitmq-cluster-health.rb -w {{ rabbitmq_management_bind_address }} -i /opt/sensu/rabbitmq.ini" + - name: rabbitmq-messages + command: "check-rabbitmq-messages.rb --host {{ rabbitmq_management_bind_address }} -i /opt/sensu/rabbitmq.ini --warn 100 --critical 250" + - name: rabbitmq-network-partitions + command: "check-rabbitmq-network-partitions.rb --host {{ rabbitmq_management_bind_address }} -i /opt/sensu/rabbitmq.ini" + - name: rabbitmq-node-health + command: "check-rabbitmq-node-health.rb --host {{ rabbitmq_management_bind_address }} -i /opt/sensu/rabbitmq.ini" + vars: + sensu_service: rabbitmq + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - galera \ No newline at end of file diff --git a/playbooks/roles/sensu_client/defaults/main.yml b/playbooks/roles/sensu_client/defaults/main.yml new file mode 100644 index 0000000..f0633db --- /dev/null +++ b/playbooks/roles/sensu_client/defaults/main.yml @@ -0,0 +1,20 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE(mnaser): These need to be defined for things this role to connect +# to your RabbitMQ properly. +# sensu_rabbitmq_host: +# sensu_rabbitmq_user: +# sensu_rabbitmq_password: \ No newline at end of file diff --git a/playbooks/roles/sensu_client/files/sudoers b/playbooks/roles/sensu_client/files/sudoers new file mode 100644 index 0000000..6d1617b --- /dev/null +++ b/playbooks/roles/sensu_client/files/sudoers @@ -0,0 +1,2 @@ +# allow using only the binary name instead of the full path in check definitions +Defaults:sensu secure_path="/opt/sensu/embedded/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" diff --git a/playbooks/roles/sensu_client/meta/main.yml b/playbooks/roles/sensu_client/meta/main.yml new file mode 100644 index 0000000..7d1d5b3 --- /dev/null +++ b/playbooks/roles/sensu_client/meta/main.yml @@ -0,0 +1,25 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +galaxy_info: + author: VEXXHOST, Inc. + description: Installs and configures sensu-client + license: Apache-2.0 + min_ansible_version: 2.7 + platforms: + - name: el7 + +dependencies: + - sensu_common \ No newline at end of file diff --git a/playbooks/roles/sensu_client/tasks/main.yml b/playbooks/roles/sensu_client/tasks/main.yml new file mode 100644 index 0000000..1d086c6 --- /dev/null +++ b/playbooks/roles/sensu_client/tasks/main.yml @@ -0,0 +1,42 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Install repositories + yum_repository: + name: sensu + description: sensu + baseurl: https://sensu.global.ssl.fastly.net/yum/$releasever/$basearch/ + gpgkey: https://repositories.sensuapp.org/yum/pubkey.gpg + +- name: Install packages + package: + name: sensu + state: installed + +- name: Configure RabbitMQ + template: + src: rabbitmq.json.j2 + dest: /etc/sensu/conf.d/rabbitmq.json + notify: Restart sensu-client + +- name: Configure sudoers + copy: + src: sudoers + dest: /etc/sudoers.d/sensu + +- name: Start service + service: + name: sensu-client + state: started \ No newline at end of file diff --git a/playbooks/roles/sensu_client/templates/rabbitmq.json.j2 b/playbooks/roles/sensu_client/templates/rabbitmq.json.j2 new file mode 100644 index 0000000..494c7b3 --- /dev/null +++ b/playbooks/roles/sensu_client/templates/rabbitmq.json.j2 @@ -0,0 +1,7 @@ +{ + "rabbitmq": { + "host": "{{ sensu_rabbitmq_host }}", + "user": "{{ sensu_rabbitmq_user }}", + "password": "{{ sensu_rabbitmq_password }}" + } +} diff --git a/playbooks/roles/sensu_common/handlers/main.yml b/playbooks/roles/sensu_common/handlers/main.yml new file mode 100644 index 0000000..d831098 --- /dev/null +++ b/playbooks/roles/sensu_common/handlers/main.yml @@ -0,0 +1,19 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Restart sensu-client + service: + name: sensu-client + state: restarted \ No newline at end of file diff --git a/playbooks/setup-everything.yml b/playbooks/setup-everything.yml new file mode 100644 index 0000000..238c228 --- /dev/null +++ b/playbooks/setup-everything.yml @@ -0,0 +1,18 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- import_playbook: setup-hosts.yml +- import_playbook: setup-infrastructure.yml +# - import_playbook: setup-openstack.yml \ No newline at end of file diff --git a/playbooks/setup-hosts.yml b/playbooks/setup-hosts.yml new file mode 100644 index 0000000..aa110dc --- /dev/null +++ b/playbooks/setup-hosts.yml @@ -0,0 +1,16 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- import_playbook: openstack-hosts-setup.yml \ No newline at end of file diff --git a/playbooks/setup-infrastructure.yml b/playbooks/setup-infrastructure.yml new file mode 100644 index 0000000..2badd00 --- /dev/null +++ b/playbooks/setup-infrastructure.yml @@ -0,0 +1,20 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- import_playbook: haproxy-install.yml +- import_playbook: memcached-install.yml +- import_playbook: galera-install.yml +- import_playbook: rabbitmq-install.yml +- import_playbook: ceph-install.yml \ No newline at end of file diff --git a/playbooks/templates/my.cnf.j2 b/playbooks/templates/my.cnf.j2 new file mode 100644 index 0000000..88253d1 --- /dev/null +++ b/playbooks/templates/my.cnf.j2 @@ -0,0 +1,7 @@ + +# {{ ansible_managed }} + +[client] +host = {{ galera_wsrep_address }} +user = sensu +password = {{ sensu_galera_password }} \ No newline at end of file diff --git a/playbooks/templates/rabbitmq.ini.j2 b/playbooks/templates/rabbitmq.ini.j2 new file mode 100644 index 0000000..0ee5700 --- /dev/null +++ b/playbooks/templates/rabbitmq.ini.j2 @@ -0,0 +1,3 @@ +[auth] +username = sensu +password = {{ sensu_monitoring_rabbitmq_password }} \ No newline at end of file diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000..74df13d --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +ansible-lint==4.1.0 \ No newline at end of file diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..77c9f62 --- /dev/null +++ b/tox.ini @@ -0,0 +1,19 @@ +[tox] +minversion = 2.0 +skipsdist = True + +[testenv] +basepython = python3 + +[testenv:linters] +deps = + -r{toxinidir}/test-requirements.txt +commands = + ansible-lint playbooks/setup-everything.yml + +[testenv:docs] +deps = + -r{toxinidir}/doc/requirements.txt +commands = + doc8 doc + sphinx-build -W -b html -d doc/build/doctrees doc/source doc/build/html \ No newline at end of file diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml new file mode 100644 index 0000000..2add2df --- /dev/null +++ b/zuul.d/project.yaml @@ -0,0 +1,27 @@ +--- +# Copyright 2019 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- project: + check: + jobs: + - opendev-tox-docs + - tox-linters + gate: + jobs: + - opendev-tox-docs + - tox-linters + promote: + jobs: + - opendev-promote-docs \ No newline at end of file