From 94e2ccb9a1ef9cb01fc89069e94fad431e9f3c7b Mon Sep 17 00:00:00 2001 From: Karl Goetz Date: Sun, 26 Feb 2017 19:26:34 +1100 Subject: [PATCH] Big refresh of role (includes making it work) This role is now usable to install and configure shinken and have a working web ui. There are some known problems listed on github but it will DTRT for now. --- README.md | 68 ++++++++++++++++++++++++++-- defaults/main.yml | 62 +++++++++++++++++-------- tasks/configure-hosts.yml | 11 ----- tasks/configure-jessie-repo.yml | 4 -- tasks/configure-shinken-contacts.yml | 9 ---- tasks/configure-shinken-hosts.yml | 11 ----- tasks/configure-shinken-webui.yml | 48 ++++++++++++++++++-- tasks/configure-shinken.yml | 47 +++++++++++++++++++ tasks/install-shinken-packages.yml | 21 +++++---- tasks/main.yml | 9 ++-- tasks/prepare-for-install.yml | 31 +++++++++++++ templates/broker-webui.cfg.tmpl | 49 -------------------- templates/contacts.cfg.tmpl | 26 ++++++++--- templates/hostgroups-all.cfg.tmpl | 7 +++ templates/hostgroups.cfg.tmpl | 7 +++ templates/hosts.cfg.tmpl | 30 ++++++++++++ templates/hosts.tmpl | 17 ------- templates/ping.cfg.tmpl | 9 ---- templates/services.cfg.tmpl | 27 +++++++++++ templates/webui-module.cfg.tmpl | 36 +++++++++++++++ 20 files changed, 372 insertions(+), 157 deletions(-) delete mode 100644 tasks/configure-hosts.yml delete mode 100644 tasks/configure-jessie-repo.yml delete mode 100644 tasks/configure-shinken-contacts.yml delete mode 100644 tasks/configure-shinken-hosts.yml create mode 100644 tasks/configure-shinken.yml create mode 100644 tasks/prepare-for-install.yml delete mode 100644 templates/broker-webui.cfg.tmpl create mode 100644 templates/hostgroups-all.cfg.tmpl create mode 100644 templates/hostgroups.cfg.tmpl create mode 100644 templates/hosts.cfg.tmpl delete mode 100644 templates/hosts.tmpl delete mode 100644 templates/ping.cfg.tmpl create mode 100644 templates/services.cfg.tmpl create mode 100644 templates/webui-module.cfg.tmpl diff --git a/README.md b/README.md index 99fb222..6d86e00 100644 --- a/README.md +++ b/README.md @@ -4,29 +4,87 @@ Shinken This role is to install Shinken and configure your hosts and services. Currently at an early stage and not quite ready for other peoples networks. +virtualenv support was coded but since shinken doesn't play nicely in a +virtualenv those code paths have been disabled. + Requirements ------------ -Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. Role Variables -------------- -A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. +The following are set via defaults/main.yml *and currently usable* (some things +have not been implemented yet) + + + # How should things be installed, 'packages' or 'pip' + shinken_install_from: 'pip' + + # Path of broker configuration + shinken_config_broker: /etc/shinken/brokers/ + + # Do we want the web UI? + shinken_enable_web_ui2: true + + # List of modules to enable in the broker. 'webui2' enables web interface. + shinken_broker_modules: 'webui2' + + # Shinken web UI configuration, only changed items are here so far. + shinken_broker_webui_host: 0.0.0.0 + shinken_broker_webui_port: 7767 + shinken_broker_webui_auth_secret: SiteSpecificAuthSecret # MUST BE CHANGED + + # Where are contacts placed + shinken_config_contacts: /etc/shinken/contacts/ + + # Details of the available contacts (include password for internal authentication) + # This example shows both expanded and single line list format for admin and guest. + shinken_contacts: + - contact_name: 'admin' + email: 'shinken@localhost' + password: 'password' + is_admin: 1 + expert: 1 + can_submit_commands: 1 + - { contact_name: 'guest', email: 'guest@localhost', password: 'password'} + + # where does service configuration go? + shinken_config_services: /etc/shinken/services/ + + # What services are we monitoring? which hostgroups do they apply to? + shinken_services: + - { service_description: 'ping test', command: 'check_ping', hostgroup_name: [] } + + # Where should the host configuration go + shinken_config_hosts: /etc/shinken/hosts/ + shinken_config_hostgroups: /etc/shinken/hostgroups/ + + # Which hosts are we monitoring? NOTE: hostgroups list is a required field, even if empty. + shinken_hosts: + - { host_name: 'router.local' , hostgroups: [ 'infrastructure' ]} + - { host_name: 'modem.local', parent: 'router.local', hostgroups: [ 'appliances' ] } + - { host_name: 'shinken.io', parent: 'modem.local', hostgroups: [ 'remote-server', 'web-server' ] } + Dependencies ------------ -A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. +This module requires epel on centos for virtualenvs and shinken packages. Roles +to perform these tasks are below, but any roles / tasks to organise the +dependenies will work. + + ansible-galaxy install wtanaka.virtualenv + ansible-galaxy install geerlingguy.repo-epel Example Playbook ---------------- Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: - - hosts: servers + - hosts: shinken roles: - - { role: username.rolename, x: 42 } + - { role: goetz.shinken, shinken_broker_modules: webui } License ------- diff --git a/defaults/main.yml b/defaults/main.yml index e379336..62dd69e 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,30 +1,52 @@ --- + +# How should things be installed, 'packages' or 'pip' +shinken_install_from: 'pip' + +# Where pip will install packages +shinken_virtualenv: /srv/shinken/environment + +# Path of broker configuration +shinken_config_broker: /etc/shinken/brokers/ + +# Do we want the web UI? +shinken_enable_web_ui2: true + +# List of modules to enable in the broker. 'webui2' enables web interface. +shinken_broker_modules: 'webui2' + # Shinken web UI configuration, only changed items are here so far. shinken_broker_webui_host: 0.0.0.0 shinken_broker_webui_port: 7767 -shinken_broker_webui_auth_secret: SiteSpecificAuthSecret +shinken_broker_webui_auth_secret: SiteSpecificAuthSecret # MUST BE CHANGED -# Details of the administrator contact. -shinken_config_contacts_name: admin -shinken_config_contacts_email: shinken@localhost -shinken_config_contacts_password: password +# Where are contacts placed +shinken_config_contacts: /etc/shinken/contacts/ -# Where should the host configuration go -shinken_config_hosts: /etc/shinken/hosts/ -# where do service configuration go? +# Details of the available contacts (include password for internal authentication) +shinken_contacts: + - contact_name: 'admin' + email: 'shinken@localhost' + password: 'password' + is_admin: 1 + expert: 1 + can_submit_commands: 1 +# - { contact_name: 'guest', email: 'guest@localhost', password: 'password'} + +# where does service configuration go? shinken_config_services: /etc/shinken/services/ -# Which hosts are we monitoring? -shinken_targets: -***REMOVED*** -***REMOVED*** -***REMOVED*** -***REMOVED*** -***REMOVED*** -***REMOVED*** -***REMOVED*** -***REMOVED*** -***REMOVED*** + # What services are we monitoring? shinken_services: - - { } + - { service_description: 'ping test', command: 'check_ping', hostgroup_name: [] } + +# Where should the host configuration go +shinken_config_hosts: /etc/shinken/hosts/ +shinken_config_hostgroups: /etc/shinken/hostgroups/ + +# Which hosts are we monitoring? +shinken_hosts: + - { host_name: 'router.local' , hostgroups: [ 'infrastructure' ]} + - { host_name: 'modem.local', parent: 'router.local', hostgroups: [ 'appliances' ] } + - { host_name: 'shinken.io', parent: 'modem.local', hostgroups: [ 'remote-server', 'web-server' ] } diff --git a/tasks/configure-hosts.yml b/tasks/configure-hosts.yml deleted file mode 100644 index 6a908ba..0000000 --- a/tasks/configure-hosts.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- name: Create configuration for hosts to monitor - template: - dest=/etc/shinken/hosts/{{ hostvars[item]['ansible_hostname'] }}.cfg - src=hosts.tmpl - when: hostvars[item]['ansible_hostname'] is defined - with_items: shinken_targets - -# TODO: figure out how to set the parent node per host in a useful way. -# with_items: groups['all'] - diff --git a/tasks/configure-jessie-repo.yml b/tasks/configure-jessie-repo.yml deleted file mode 100644 index 491c138..0000000 --- a/tasks/configure-jessie-repo.yml +++ /dev/null @@ -1,4 +0,0 @@ -# This should only be used while installing shinken -- name: Enable jessie (testing) for package installs - copy: content='deb http://ftp.iinet.net.au/debian/debian/ jessie main' dest=/var/lib/ansible/jessie.sources.list group=root owner=root - diff --git a/tasks/configure-shinken-contacts.yml b/tasks/configure-shinken-contacts.yml deleted file mode 100644 index 3c90295..0000000 --- a/tasks/configure-shinken-contacts.yml +++ /dev/null @@ -1,9 +0,0 @@ -# This doubles as the login details -- name: Configure shinken admin user and login - template: - src=contacts.cfg.tmpl - dest=/etc/shinken/contacts.cfg - mode=640 - notify: - - restart shinken arbiter - diff --git a/tasks/configure-shinken-hosts.yml b/tasks/configure-shinken-hosts.yml deleted file mode 100644 index a7bed8c..0000000 --- a/tasks/configure-shinken-hosts.yml +++ /dev/null @@ -1,11 +0,0 @@ -- name: Install hosts.cfg -# copy: src=shinken-hosts/ dest=/etc/shinken/hosts/ - template: user=root owner=root - src=hosts.tmpl -# how do we get loop to pass in items? - with_items: - - loop over hosts here - notify: - - restart shinken arbiter - - diff --git a/tasks/configure-shinken-webui.yml b/tasks/configure-shinken-webui.yml index 2602188..a822d8e 100644 --- a/tasks/configure-shinken-webui.yml +++ b/tasks/configure-shinken-webui.yml @@ -1,6 +1,46 @@ -- name: Set up Shinken web ui - template: src=broker-webui.cfg.tmpl dest=/etc/shinken/shinken-specific/broker-webui.cfg - owner=root group=root mode=444 +--- +# https://github.com/shinken-monitoring/mod-webui/wiki/Installation + +# - name: Install Web UI configuration +# template: src=webui-module.cfg.tmpl dest=/etc/shinken/modules/broker-webui.cfg +# owner=root group=root mode=444 +# notify: +# - restart shinken broker +# - restart shinken arbiter + +# A 'with items' doesn't work here for some reason +- name: Install webui2 python dependencies + pip: + state: present + name: "pymongo>=3.0.3 passlib requests arrow bottle==0.12.8" +# virtualenv: {{ shinken_virtualenv }} + +- name: Install mongodb for storing WebUI user preferences + package: + name: mongodb + state: present + +- name: Set up Shinken CLI + become: true + become_user: shinken + command: shinken --init + args: + creates: /home/shinken/.shinken.ini + +- name: Install Shinken WebUI 2 + become: true + become_user: shinken + command: shinken install webui2 + args: + creates: /etc/shinken/modules/webui2.cfg + +- name: Change broker-master configuration + lineinfile: + dest={{ shinken_config_broker }}/broker-master.cfg + state=present + regexp='.*[^#] modules.*' + line=" modules {{ shinken_broker_modules }}" notify: - restart shinken broker - + - restart shinken arbiter + diff --git a/tasks/configure-shinken.yml b/tasks/configure-shinken.yml new file mode 100644 index 0000000..2f1a984 --- /dev/null +++ b/tasks/configure-shinken.yml @@ -0,0 +1,47 @@ +--- + +- name: Configure shinken users for contact and authentication + with_items: "{{ shinken_contacts }}" + template: + src=contacts.cfg.tmpl + dest={{ shinken_config_contacts }}/{{ item.contact_name |mandatory }}.cfg + mode=640 + notify: + - restart shinken arbiter + +- name: Create configuration for services to monitor + with_items: "{{ shinken_services }}" + template: + dest={{ shinken_config_services }}/{{ item.service_description|replace(' ', '_') }}.cfg + src=services.cfg.tmpl + notify: + - restart shinken arbiter + +- name: Create configuration for hosts to monitor (without services) + with_items: "{{ shinken_hosts }}" + template: + dest={{ shinken_config_hosts }}/{{ item.host_name }}.cfg + src=hosts.cfg.tmpl + notify: + - restart shinken arbiter + +# Following Jinja magic thanks to mikecee +- name: Build list of hostgroups + set_fact: + hglist="{{ shinken_hosts | sum(attribute='hostgroups', start=[]) | unique }}" + +- name: Create configuration for hostgroups + with_items: "{{ hglist }}" + template: + dest={{ shinken_config_hostgroups }}/{{ item }}.cfg + src=hostgroups.cfg.tmpl + notify: + - restart shinken arbiter + +- name: Install 'all' hostgroup + template: + dest={{ shinken_config_hostgroups }}/all.cfg + src=hostgroups-all.cfg.tmpl + notify: + - restart shinken arbiter + diff --git a/tasks/install-shinken-packages.yml b/tasks/install-shinken-packages.yml index 59ec9e9..8cb5928 100644 --- a/tasks/install-shinken-packages.yml +++ b/tasks/install-shinken-packages.yml @@ -1,10 +1,15 @@ -- name: Install shinken including web UI - command: apt-get -o Dir::Etc::SourceParts=/var/lib/ansible/jessie.sources.list install {{ item }} - creates=/etc/init.d/shinken - with_items: - - shinken - - shinken-module-arbiter-hotdependencies +--- +- name: Install Shinken from OS packages + when: shinken_install_from == "packages" + package: + name: shinken + state: present -- name: Allow bi directional HTTP access to shinken frontend on 7767 - ufw: rule=allow port=7767 proto=tcp +- name: Install Shinken using pip + when: shinken_install_from == "pip" + pip: + name: Shinken + state: present +# virtualenv: "{{ shinken_virtualenv }}" +# virtualenv_site_packages: yes diff --git a/tasks/main.yml b/tasks/main.yml index aed1d74..deacfb1 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,9 +1,10 @@ --- -# Couldn't get pinning working so i've had to do this the long and work aroundy way -- include: configure-jessie-repo.yml +- include: prepare-for-install.yml + - include: install-shinken-packages.yml +- include: configure-shinken.yml + - include: configure-shinken-webui.yml -- include: configure-shinken-contacts.yml -- include: configure-shinken-hosts.yml + when: "{{ shinken_enable_web_ui2 }}" diff --git a/tasks/prepare-for-install.yml b/tasks/prepare-for-install.yml new file mode 100644 index 0000000..5d877e4 --- /dev/null +++ b/tasks/prepare-for-install.yml @@ -0,0 +1,31 @@ +--- +- name: Create shinken group + user: + name: shinken + system: yes + +- name: Create shinken user + user: + name: shinken + comment: Created by ansible-shinken + group: shinken + system: yes + +# - name: Create directory for shinken to be installed to +# when: shinken_install_from == "pip" +# file: +# path: "{{ shinken_virtualenv }}" +# state: directory + +# Required by shinken http_client but not pulled in as a dependency +- name: Install python-pycurl + package: + name: python-pycurl + state: present + +# needed to install shinken and its web ui +- name: Install python-pip + package: + name: python-pip + state: present + diff --git a/templates/broker-webui.cfg.tmpl b/templates/broker-webui.cfg.tmpl deleted file mode 100644 index bc7129c..0000000 --- a/templates/broker-webui.cfg.tmpl +++ /dev/null @@ -1,49 +0,0 @@ -# {{ ansible_managed }} -## Module: WebUI -## Loaded by: Broker -# The Shinken web interface and integrated web server. -define module { - module_name WebUI - module_type webui - host {{ shinken_broker_webui_host }} ; All interfaces = 0.0.0.0 - port {{ shinken_broker_webui_port }} - # auth_secret CHANGE_ME ; CHANGE THIS or someone could forge - auth_secret {{ shinken_broker_webui_auth_secret }} - ; cookies!! - allow_html_output 0 ; Allow or not HTML chars in plugins output. - ; WARNING: Allowing can be a security issue. - max_output_length 100 ; Maximum output length for plugin output in webui - manage_acl 1 ; Use contacts ACL. 0 allow actions for all. - play_sound 0 ; Play sound on new non-acknowledged problems. - #login_text Welcome on Shinken WebUI ; Text in the login form. - - ## Modules for WebUI - # - Apache_passwd = Use an htpasswd file for auth backend. - # - ActiveDir_UI = Use AD for auth backend (and retrieve photos). - # - Cfg_password = Use the password setted in Shinken contact for auth. - # - PNP_UI = Use PNP graphs in the UI. - # - GRAPHITE_UI = Use graphs from Graphite time series database. - # - Mongodb = Save user preferences to a Mongodb database - # - SQLitedb = Save user preferences to a SQLite database - #modules Apache_passwd, ActiveDir_UI, Cfg_password, PNP_UI, Mongodb, Glances_UI - modules SQLitedb,Cfg_password - - ## Advanced Options - # Don't use them as long as you don't know what you are doing! - #http_backend auto ; Choice is: auto, wsgiref, cherrypy, flup, - ; flupscgi, paste, tornado, twisted or gevent. - ; Leave auto to find the best available. - #remote_user_enable 1 ; If WebUI is behind a web server which - ; has already authentified user, enable. - #remote_user_enable 2 ; Look for remote user in the WSGI environment - ; instead of the HTTP header. This allows - ; for fastcgi (flup) and scgi (flupscgi) - ; integration, eg. with the apache modules. - #remote_user_variable X_Remote_User ; Set to the HTTP header containing - ; the authentificated user s name, which - ; must be a Shinken contact. - # If you got external plugins (pages) to load on webui - #additional_plugins_dir - -} - diff --git a/templates/contacts.cfg.tmpl b/templates/contacts.cfg.tmpl index be71371..cb038e4 100644 --- a/templates/contacts.cfg.tmpl +++ b/templates/contacts.cfg.tmpl @@ -1,10 +1,24 @@ # {{ ansible_managed }} define contact{ - use generic-contact - contact_name {{ shinken_config_contacts_name }} - email {{ shinken_config_contacts_email }} - pager 0600000000 ; contact phone number - password {{ shinken_config_contacts_password }} - is_admin 1 + {# loop through all key:value pairs and print out the results #} + {% for key, value in item.iteritems() %} + + {% if key == 'use' %} + {% if key is defined %} + {{ key }} {{ value }} + {% else %} + {{ key }} generic-contact + {% endif %} + {% elif key == 'contact_name' %} + {% if key is defined %} + {{ key }} {{ value }} + {% else %} + {{ key }} {{ value |mandatory }} + {% endif %} + {% else %} + {# Guess none of the special cases apply here #} + {{ key }} {{ value }} + {% endif %} + {% endfor %} } diff --git a/templates/hostgroups-all.cfg.tmpl b/templates/hostgroups-all.cfg.tmpl new file mode 100644 index 0000000..9d2332a --- /dev/null +++ b/templates/hostgroups-all.cfg.tmpl @@ -0,0 +1,7 @@ +# {{ ansible_managed }} + +define hostgroup { + hostgroup_name all + alias all + } + diff --git a/templates/hostgroups.cfg.tmpl b/templates/hostgroups.cfg.tmpl new file mode 100644 index 0000000..07e993a --- /dev/null +++ b/templates/hostgroups.cfg.tmpl @@ -0,0 +1,7 @@ +# {{ ansible_managed }} + +define hostgroup { + hostgroup_name {{ item }} + alias {{ item }} + } + diff --git a/templates/hosts.cfg.tmpl b/templates/hosts.cfg.tmpl new file mode 100644 index 0000000..7ff4f22 --- /dev/null +++ b/templates/hosts.cfg.tmpl @@ -0,0 +1,30 @@ +# {{ ansible_managed }} + +define host{ + {# loop through all key:value pairs and print out the results #} + {% for key, value in item.iteritems() %} + + {% if key == 'use' %} + {% if key is defined %} + {{ key }} {{ value }} + {% else %} + {{ key }} generic-host + {% endif %} + {% elif key == 'parent' %} + {% if value %} + # Parent nodes of this host + parents {{ value }} + {% endif %} + {% elif key == 'contact_groups' %} + # Contact groups this host is a member of + contact_groups {{ value | join(",") }} + {% elif key == 'hostgroups' %} + # Hostgroups this host is a member of + hostgroups {{ value | join(",") }},all + {% else %} + {# Guess none of the special cases apply here #} + {{ key }} {{ value }} + {% endif %} + {% endfor %} +} + diff --git a/templates/hosts.tmpl b/templates/hosts.tmpl deleted file mode 100644 index 1c4bb39..0000000 --- a/templates/hosts.tmpl +++ /dev/null @@ -1,17 +0,0 @@ -# {{ ansible_managed }} -############################################################################### -# -# HOST DEFINITION -# -############################################################################### - -# Define a host for the local machine -define host{ - use linux - host_name {{ item.hostname }} - address {{ item.hostname }} -{% if item.parent != '' %} - parents {{ item.parent }} -{% endif %} -} - diff --git a/templates/ping.cfg.tmpl b/templates/ping.cfg.tmpl deleted file mode 100644 index 753cfca..0000000 --- a/templates/ping.cfg.tmpl +++ /dev/null @@ -1,9 +0,0 @@ -# {{ ansible_managed }} - -# Define a service to "ping" the local machine -define service{ - use generic-service ; Name of service template to use - host_name medeopolis.com - service_description PING - check_command {{ shinken_cfg_ping_check_command |default('check_ping!100.0,20%!500.0,60%') }} - } diff --git a/templates/services.cfg.tmpl b/templates/services.cfg.tmpl new file mode 100644 index 0000000..054a990 --- /dev/null +++ b/templates/services.cfg.tmpl @@ -0,0 +1,27 @@ +# {{ ansible_managed }} + +define service{ + {# loop through all key:value pairs and print out the results #} + {% for key, value in item.iteritems() %} + {% if key == 'use' %} + {% if key is defined %} + {{ key }} {{ value }} + {% endif %} + {% elif key == 'check_command' %} + {% if key is defined %} + {{ key }} {{ value }} + {% else %} + check_command this value is required and was not set in ansible + {% endif %} + {% elif key == 'hostgroup_name' %} + {{ key }} {{ value |join(",") }} + {% else %} + {# Guess none of the special cases apply here #} + {{ key }} {{ value }} + {% endif %} + {% endfor %} + {# We can have multiple sources but its good to have this one as default. Fills in any gaps left by supplied #} + use generic-service + hostgroup_name all +} + diff --git a/templates/webui-module.cfg.tmpl b/templates/webui-module.cfg.tmpl new file mode 100644 index 0000000..f9d8de8 --- /dev/null +++ b/templates/webui-module.cfg.tmpl @@ -0,0 +1,36 @@ +# {{ ansible_managed }} +## Module: WebUI +## Loaded by: Broker +# The Shinken web interface and integrated web server. +define module { + module_name WebUI + module_type webui + host {{ shinken_broker_webui_host }} ; All interfaces = 0.0.0.0 + port {{ shinken_broker_webui_port }} + auth_secret {{ shinken_broker_webui_auth_secret }} + # Allow or not the html characters in plugins output + # WARNING: so far, it can be a security issue + allow_html_output 0 + + # Option welcome message + #login_text Welcome to ACME Shinken WebUI. + + #http_backend auto + # ; can be also: wsgiref, cherrypy, paste, tornado, twisted + # ; or gevent. auto means best match in the system. + + modules Apache_passwd,ActiveDir_UI,Cfg_password,Mongodb + + # Modules available for the WebUI: + # + # Note: Choose one or more authentication methods. + # + # Apache_passwd: use an Apache htpasswd files for auth + # ActiveDir_UI: use AD for auth and photo collect + # Cfg_password: use passwords in contacts configuration for authentication + # + # PNP_UI: Use PNP graphs in the UI + # GRAPHITE_UI: Use graphs from Graphite + # + # Mongodb: Necessary for enabling user preferences in WebUI +}