From 637f7cc8e204145582a80f4b713492632f92a2d5 Mon Sep 17 00:00:00 2001 From: Daniel Bodky Date: Tue, 21 Nov 2023 13:23:15 +0100 Subject: [PATCH 01/15] Updates available roles --- doc/getting-started.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/getting-started.md b/doc/getting-started.md index 6fd1ce35..17ab2c68 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -1,11 +1,19 @@ ### Getting Started -The collection includes two roles in the current version. +The collection includes six roles in the current version. * icinga.repos: Role to manage repositories * [Documentation: doc/role-repos](role-repos/role-repos.md) * icinga.icinga2: Role to install and manage Icinga 2 instances. * [Documentation: doc/role-icinga2](role-icinga2/role-icinga2.md) +* icinga.icingadb: Role to install and manage IcingaDB, Icinga2's new data backend. + * [Documentation: doc/role-icingadb](role-icingadb/role-icingadb.md) +* icinga.icingadb_redis: Role to install and manage Redis, IcingaDB's cache backend. + * [Documentation: doc/role-icingadb_redis](role-icingadb_redis/role-icingadb_redis.md) +* icinga.icingaweb2: Role to install and manage Icinga Web 2. + * [Documentation: doc/role-icingaweb2](role-icingaweb2/role-icingaweb2.md) +* icinga.monitoring_plugins: Role to install and manage Icinga2 compatible monitoring plugins. + * [Documentation: doc/role-monitoring_plugins](role-monitoring_plugins/role-monitoring_plugins.md) --- From 6ab1d1f20483a1d45c689c82e33a4e30537e18f4 Mon Sep 17 00:00:00 2001 From: Daniel Bodky Date: Tue, 21 Nov 2023 13:39:54 +0100 Subject: [PATCH 02/15] Adds references to the database examples to relevant parts of the docs --- doc/getting-started.md | 30 ++++++++++++++++++++++++++ doc/role-icingadb/role-icingadb.md | 7 +++++- doc/role-icingaweb2/role-icingaweb2.md | 4 ++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/doc/getting-started.md b/doc/getting-started.md index 17ab2c68..851df2a7 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -47,6 +47,36 @@ ansible-galaxy collection build ansible-collection-icinga ansible-galaxy collection install icinga-icinga-0.3.0.tar.gz ``` +## Databases + +Icinga2 relies on relational databases for many parts of its functionality. **None** of those databases gets installed by the roles. You need to install and configure them yourself. For doing so, there are many ways available, e.g. the Ansible role [geerlingguy.mysql](https://galaxy.ansible.com/geerlingguy/mysql) for MySQL flavour (both MySQL and MariaDB) or [geerlingguy.postgresql](https://galaxy.ansible.com/geerlingguy/postgresql) PostGresQL: + +```yaml +- name: Configure databases for Icinga2 + hosts: database + vars: + mysql_databases: + - name: icingadb + - name: icingaweb + - name: vspheredb + encoding: utf8mb4 + collation: utf8mb4_unicode_ci + - name: director + mysql_users: + - name: icingadb-user + host: localhost + password: icingadb-password + priv: "icingadb.*:ALL" + [...] + roles: + - role: geerlingguy.mysql +``` + +> [!NOTE] +> Schema migrations needed for the respective Icinga components to work will be handled either by the respective roles or by the Icinga components themselves. + + + ## Example Playbooks This is an example on how to install an Icinga 2 server/master instance. diff --git a/doc/role-icingadb/role-icingadb.md b/doc/role-icingadb/role-icingadb.md index 5d66a32a..e30742ab 100644 --- a/doc/role-icingadb/role-icingadb.md +++ b/doc/role-icingadb/role-icingadb.md @@ -5,7 +5,12 @@ This role installs and configures the IcingaDB daemon. In addition it can also i It serves as the official, more performant successor to Icinga IDO. More information about its purpose and design can be found [in the official documentation](https://icinga.com/docs/icinga-db/latest/doc/01-About/). -> :information_source: In many scenarios you want to install the [icingadb_redis role](../role-icingadb_redis/) together with this role. It is part of this collection, too. +> [!TIP] +> In many scenarios you want to install the [icingadb_redis role](../role-icingadb_redis/) together with this role. It is part of this collection, too. + +## Database + +IcingaDB relies on a relational database to persist received data. This database **won't** be created by this role - you need to deploy and configure one in advance. For more information, see the [Databases](../getting-started.md#databases) section in the getting started guide. ## Variables diff --git a/doc/role-icingaweb2/role-icingaweb2.md b/doc/role-icingaweb2/role-icingaweb2.md index 4faf1ae7..bff00b7c 100644 --- a/doc/role-icingaweb2/role-icingaweb2.md +++ b/doc/role-icingaweb2/role-icingaweb2.md @@ -7,6 +7,10 @@ The role icingaweb2 installs and configures Icinga Web 2 and its modules. * [IcingaDB](./module-icingadb.md) * [Monitoring](./module-monitoring.md) +## Databases + +Icingaweb2 and some of its modules rely on a relational database to persist data. These databases **won't** be created by this role - you need to deploy and configure them in advance. For more information, see the [Databases](../getting-started.md#databases) section in the getting started guide. + ## Variables ### Icinga Web 2 DB Configuration From b96d50d11f907a40aa52855f248ee8e2a18075cb Mon Sep 17 00:00:00 2001 From: Daniel Bodky Date: Tue, 21 Nov 2023 13:40:51 +0100 Subject: [PATCH 03/15] add installation for x509 module (#214) * add module x509 and mysql imports task * Add documentation for x509 module * Add documentation about database imports * Continues working on x509 module installation --------- Co-authored-by: Thilo W --- .../feature_add_x509_module_installation.yml | 3 + doc/role-icingaweb2/module-x509.md | 95 +++++++++++++++++++ roles/icingaweb2/tasks/main.yml | 8 ++ .../icingaweb2/tasks/manage_mysql_imports.yml | 38 ++++++++ roles/icingaweb2/tasks/modules/x509.yml | 66 +++++++++++++ roles/icingaweb2/vars/main.yml | 3 +- 6 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/feature_add_x509_module_installation.yml create mode 100644 doc/role-icingaweb2/module-x509.md create mode 100644 roles/icingaweb2/tasks/manage_mysql_imports.yml create mode 100644 roles/icingaweb2/tasks/modules/x509.yml diff --git a/changelogs/fragments/feature_add_x509_module_installation.yml b/changelogs/fragments/feature_add_x509_module_installation.yml new file mode 100644 index 00000000..82c1f981 --- /dev/null +++ b/changelogs/fragments/feature_add_x509_module_installation.yml @@ -0,0 +1,3 @@ +--- +major_changes: + - Added Installation of x509 certificate monitoring model diff --git a/doc/role-icingaweb2/module-x509.md b/doc/role-icingaweb2/module-x509.md new file mode 100644 index 00000000..684000fd --- /dev/null +++ b/doc/role-icingaweb2/module-x509.md @@ -0,0 +1,95 @@ +## Module x509 + +### Variables and Configuration + +The general module parameter like `enabled` and `source` can be applied here. + +| Variable | Value | +|----------|------------| +| enabled | true/false | +| source | package | + +#### Section configuration + +The backend database for the module needs to be available and configured at the `icingaweb2_resources` variable. + +``` +icingaweb2_modules: + x509: + source: package + enabled: true + config: + backend: + resource: x509 +``` + +#### Configure SNI Names. + +To configure SNIs for a IP address, use the dictionary `sni`. + +Example: + +``` +icingaweb2_modules: + x509: + source: package + enabled: true + config: + backend: + resource: x509 + sni: + 192.168.56.213: + hostnames: + - icinga.com + - test2.icinga.com +``` + +#### Import Certificates + +To import certificates use the **list** `certificate_files` all files need to be +available locally beforehand. + +``` +icingaweb2_modules: + x509: + source: package + enabled: true + config: + backend: + resource: x509 + certificate_files: + - /etc/ssl/certs/ca-certificates.crt +``` + +#### Database Schema Setup + +To import the database schema use `database` dictionary with the following variables. + +| Variable | Type | Description | Default | +|----------|------|-------------|---------| +| `import_schema` | `Boolean` | Defines wether the schema will be imported or not. | false | +| `host` | `String` | Defines database address to connect to. | `localhost` | +| `port` | `int` | Defines the database port to connect to. | `3306` or `5432` | +| `user` | `string` | Defines database user | `x509` | +| `name` | `String` | Defines the database to connect to. | `x509` | +| `password` | `String` | Defines the database password to connect with. | OMITTED | +| `ssl_mode` | `String` | Clients attempt to connect using encryption, falling back to an unencrypted connection if an encrypted connection cannot be established |**n/a** | +|`ssl_ca`| `String`| Defines the path to the ca certificate for client authentication. | **n/a** | +|`ssl_cert`|`String`| Defines the path to the certificate for client authentication. | **n/a** | +|`ssl_key`| `String` | Defines the path to the certificate key for client key authentication. | **n/a** | +|`ssl_cipher`|`String`| Ciphers for the client authentication. | **n/a** | +|`ssl_extra_options`|`String`| Extra options for the client authentication. | **n/a** | + + +``` +icingaweb2_modules: + x509: + source: package + enabled: true + database: + import_schema: true + host: localhost + port: 3306 + user: x509 + password: secret +``` diff --git a/roles/icingaweb2/tasks/main.yml b/roles/icingaweb2/tasks/main.yml index e6bd7b6b..a020d4cd 100644 --- a/roles/icingaweb2/tasks/main.yml +++ b/roles/icingaweb2/tasks/main.yml @@ -43,3 +43,11 @@ force: yes when: icingaweb2_modules is defined loop: "{{ icingaweb2_modules | dict2items }}" + +# Many daemons fail before e.g. the resource is set up or the schema hasn't been migrated. This is a workaround. +- name: Manage enabled module daemons + ansible.builtin.service: + name: "icinga-{{ item.key }}" + state: restarted + when: icingaweb2_modules is defined and item.value.enabled|bool == true and item.key in ['vspheredb', 'x509'] + loop: "{{ icingaweb2_modules | dict2items }}" diff --git a/roles/icingaweb2/tasks/manage_mysql_imports.yml b/roles/icingaweb2/tasks/manage_mysql_imports.yml new file mode 100644 index 00000000..676c6df2 --- /dev/null +++ b/roles/icingaweb2/tasks/manage_mysql_imports.yml @@ -0,0 +1,38 @@ +--- +- name: Check Database Credentials + ansible.builtin.assert: + that: + - _db['user'] is defined + - _db['password'] is defined + fail_msg: "No database credentials defined." + +- name: Build mysql command + ansible.builtin.set_fact: + _tmp_mysqlcmd: >- + mysql {% if _db['host'] | default('localhost') != 'localhost' %} -h "{{ _db['host'] }}" {%- endif %} + {% if _db['port'] is defined %} -P "{{ _db['port'] }}" {%- endif %} + {% if _db['ssl_mode'] is defined %} --ssl-mode "{{ _db['ssl_mode'] }}" {%- endif %} + {% if _db['ssl_ca'] is defined %} --ssl-ca "{{ _db['ssl_ca'] }}" {%- endif %} + {% if _db['ssl_cert'] is defined %} --ssl-cert "{{ _db['ssl_cert'] }}" {%- endif %} + {% if _db['ssl_key'] is defined %} --ssl-key "{{ _db['ssl_key'] }}" {%- endif %} + {% if _db['ssl_cipher'] is defined %} --ssl-cipher "{{ _db['ssl_cipher'] }}" {%- endif %} + {% if _db['ssl_extra_options'] is defined %} {{ _db['ssl_extra_options'] }} {%- endif %} + -u "{{ _db['user'] }}" + -p"{{ _db['password'] }}" + "{{ _db['name'] }}" + +- name: MySQL check for db schema + ansible.builtin.shell: > + {{ _tmp_mysqlcmd }} + -Ns -e "{{ _db['select_query'] }}" + failed_when: false + changed_when: false + check_mode: false + register: _db_schema + +- name: MySQL import db schema + ansible.builtin.shell: > + {{ _tmp_mysqlcmd }} + < {{ _db['schema_path'] }} + when: _db_schema.rc != 0 + run_once: yes diff --git a/roles/icingaweb2/tasks/modules/x509.yml b/roles/icingaweb2/tasks/modules/x509.yml new file mode 100644 index 00000000..a0bc7e25 --- /dev/null +++ b/roles/icingaweb2/tasks/modules/x509.yml @@ -0,0 +1,66 @@ +- name: Module x509 | Ensure config directory + ansible.builtin.file: + state: directory + dest: "{{ icingaweb2_modules_config_dir }}/{{ _module }}" + owner: "{{ icingaweb2_httpd_user }}" + group: "{{ icingaweb2_group }}" + mode: "2770" + vars: + _module: "{{ item.key }}" + +- name: Module x509 | Manage config files + ansible.builtin.include_tasks: manage_module_config.yml + loop: "{{ _files }}" + loop_control: + loop_var: _file + when: vars['icingaweb2_modules'][_module][_file] is defined + vars: + _module: "{{ item.key }}" + _files: + - config + - sni + +- name: Module x509 | Manage Schema + block: + - name: Module x509 | Prepare _db informations + ansible.builtin.set_fact: + _db: + host: "{{ vars['icingaweb2_modules'][_module]['database']['host'] | default('localhost') }}" + port: "{{ vars['icingaweb2_modules'][_module]['database']['port'] | default('3306') }}" + user: "{{ vars['icingaweb2_modules'][_module]['database']['user'] | default('x509') }}" + password: "{{ vars['icingaweb2_modules'][_module]['database']['password'] | default(omit) }}" + name: "{{ vars['icingaweb2_modules'][_module]['database']['name'] | default('x509') }}" + ssl_mode: "{{ vars['icingaweb2_modules'][_module]['database']['ssl_mode'] | default(omit) }}" + ssl_ca: "{{ vars['icingaweb2_modules'][_module]['database']['ssl_ca'] | default(omit) }}" + ssl_cert: "{{ vars['icingaweb2_modules'][_module]['database']['ssl_cert'] | default(omit) }}" + ssl_key: "{{ vars['icingaweb2_modules'][_module]['database']['ssl_key'] | default(omit) }}" + ssl_cipher: "{{ vars['icingaweb2_modules'][_module]['database']['ssl_cipher'] | default(omit) }}" + ssl_extra_options: "{{ vars['icingaweb2_modules'][_module]['database']['ssl_extra_options'] | default(omit) }}" + schema_path: /usr/share/icingaweb2/modules/x509/schema/mysql.schema.sql + select_query: "select * from x509_certificate" + when: vars['icingaweb2_modules'][_module]['database']['type'] | default('mysql') == 'mysql' + + - ansible.builtin.fail: + fail_msg: "The Database type select is not supported, {{ vars['icingaweb2_modules'][_module]['database']['type'] }} [Supported=mysql]" + when: vars['icingaweb2_modules'][_module]['database']['type'] is defined and vars['icingaweb2_modules'][_module]['database']['type'] != 'mysql' + + - name: Module x509 | Import Schema + ansible.builtin.include_tasks: ../manage_mysql_imports.yml + + - name: Module x509 | empty _db var + ansible.builtin.set_fact: + _db: {} + when: vars['icingaweb2_modules'][_module]['database']['import_schema'] | default(false) + vars: + _module: "{{ item.key }}" + +- name: Module x509 | Import Certificates + ansible.builtin.shell: > + icingacli {{ _module }} import --file {{ _file }} + loop: "{{ vars['icingaweb2_modules'][_module]['certificate_files'] }}" + loop_control: + loop_var: _file + vars: + _module: "{{ item.key }}" + when: vars['icingaweb2_modules'][_module]['certificate_files'] is defined + changed_when: false diff --git a/roles/icingaweb2/vars/main.yml b/roles/icingaweb2/vars/main.yml index 8092fd97..588f0d6d 100644 --- a/roles/icingaweb2/vars/main.yml +++ b/roles/icingaweb2/vars/main.yml @@ -2,4 +2,5 @@ icingaweb2_module_packages: icingadb: icingadb-web director: icinga-director - businessprocess: icinga-businessprocess \ No newline at end of file + x509: icinga-x509 + businessprocess: icinga-businessprocess From 0a37c99bf2d264e0b71ac7d9efb09d9457baeea4 Mon Sep 17 00:00:00 2001 From: Daniel Bodky Date: Tue, 21 Nov 2023 13:52:59 +0100 Subject: [PATCH 04/15] Fixes typos --- doc/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/getting-started.md b/doc/getting-started.md index 851df2a7..8a5b6767 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -49,7 +49,7 @@ ansible-galaxy collection install icinga-icinga-0.3.0.tar.gz ## Databases -Icinga2 relies on relational databases for many parts of its functionality. **None** of those databases gets installed by the roles. You need to install and configure them yourself. For doing so, there are many ways available, e.g. the Ansible role [geerlingguy.mysql](https://galaxy.ansible.com/geerlingguy/mysql) for MySQL flavour (both MySQL and MariaDB) or [geerlingguy.postgresql](https://galaxy.ansible.com/geerlingguy/postgresql) PostGresQL: +Icinga2 relies on relational databases for many parts of its functionality. **None** of those databases get installed by the roles. You need to install and configure them yourself. For doing so, there are many ways available, e.g. the Ansible role [geerlingguy.mysql](https://galaxy.ansible.com/geerlingguy/mysql) for MySQL flavours (both MySQL and MariaDB) or [geerlingguy.postgresql](https://galaxy.ansible.com/geerlingguy/postgresql) for PostGresQL: ```yaml - name: Configure databases for Icinga2 From 1414a2291a9d0bbf59a25673a5ff4903cf36c75a Mon Sep 17 00:00:00 2001 From: losten Date: Wed, 22 Nov 2023 16:14:55 +0100 Subject: [PATCH 05/15] implemented basic usermanagment for mysql --- roles/icingaweb2/tasks/main.yml | 4 +- roles/icingaweb2/tasks/manage_db.yml | 21 ++++++ .../tasks/manage_icingaweb_mysql_db.yml | 70 ------------------- roles/icingaweb2/tasks/mysql/import_db.yml | 17 +++++ roles/icingaweb2/tasks/mysql/prepare_db.yml | 32 +++++++++ roles/icingaweb2/tasks/mysql/users_db.yml | 30 ++++++++ 6 files changed, 102 insertions(+), 72 deletions(-) create mode 100644 roles/icingaweb2/tasks/manage_db.yml delete mode 100644 roles/icingaweb2/tasks/manage_icingaweb_mysql_db.yml create mode 100644 roles/icingaweb2/tasks/mysql/import_db.yml create mode 100644 roles/icingaweb2/tasks/mysql/prepare_db.yml create mode 100644 roles/icingaweb2/tasks/mysql/users_db.yml diff --git a/roles/icingaweb2/tasks/main.yml b/roles/icingaweb2/tasks/main.yml index e6bd7b6b..baf08261 100644 --- a/roles/icingaweb2/tasks/main.yml +++ b/roles/icingaweb2/tasks/main.yml @@ -25,8 +25,8 @@ ansible.builtin.include_tasks: "manage_icingaweb_config.yml" - name: Manage Icinga Web 2 DB - ansible.builtin.include_tasks: "manage_icingaweb_{{ icingaweb2_db.type }}_db.yml" - when: icingaweb2_db is defined + ansible.builtin.include_tasks: "manage_db.yml" + when: icingaweb2_db is defined and (icingaweb2_db_import_schema | default(False) or icingaweb2_users is defined or icingaweb2_admin is defined) - name: Configure modules ansible.builtin.include_tasks: "modules/{{ item.key }}.yml" diff --git a/roles/icingaweb2/tasks/manage_db.yml b/roles/icingaweb2/tasks/manage_db.yml new file mode 100644 index 00000000..7b30f6bb --- /dev/null +++ b/roles/icingaweb2/tasks/manage_db.yml @@ -0,0 +1,21 @@ +--- + +- name: prepare database + ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/prepare_db.yml" + when: icingaweb2_db is defined + +- name: import database schema + ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/import_db.yml" + when: icingaweb2_db_import_schema | default(False) + +- name: add admin to users list + ansible.builtin.set_fact: + icingaweb2_users: '{{ icingaweb2_users + [{"username": "{{ icingaweb2_admin_username }}", "password": "{{ icingaweb2_admin_password }}", "update": "{{ icingaweb2_admin_update | default(false) }}" }]}}' + when: icingaweb2_admin_username is defined and icingaweb2_admin_password is defined + +- name: add icinga web 2 users + ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/users_db.yml" + loop: "{{ icingaweb2_users }}" + loop_control: + loop_var: _users + when: icingaweb2_users is defined diff --git a/roles/icingaweb2/tasks/manage_icingaweb_mysql_db.yml b/roles/icingaweb2/tasks/manage_icingaweb_mysql_db.yml deleted file mode 100644 index 89d992c4..00000000 --- a/roles/icingaweb2/tasks/manage_icingaweb_mysql_db.yml +++ /dev/null @@ -1,70 +0,0 @@ ---- - -- name: Check Database Credentials - ansible.builtin.assert: - that: - - icingaweb2_db['user'] is defined - - icingaweb2_db['password'] is defined - fail_msg: "No database credentials defined. Please set icingaweb2_db. or a privileged user with icingaweb2_priv_db_" - when: icingaweb2_priv_db_password is undefined and icingaweb2_priv_db_user is undefined - -- name: Set db user with admin privileges - ansible.builtin.set_fact: - _priv_db_user: "{{ icingaweb2_priv_db_user }}" - _priv_db_pass: "{{ icingaweb2_priv_db_password }}" - when: icingaweb2_priv_db_password is defined and icingaweb2_priv_db_user is defined - -- name: Ensure Icinga Web - block: - - name: Build mysql command - ansible.builtin.set_fact: - _tmp_mysqlcmd: >- - mysql {% if icingaweb2_db['host'] | default('localhost') != 'localhost' %} -h "{{ icingaweb2_db['host'] }}" {%- endif %} - {% if icingaweb2_db['port'] is defined %} -P "{{ icingaweb2_db['port'] }}" {%- endif %} - {% if icingaweb2_db['ssl_mode'] is defined %} --ssl-mode "{{ icingaweb2_db['ssl_mode'] }}" {%- endif %} - {% if icingaweb2_db['ssl_ca'] is defined %} --ssl-ca "{{ icingaweb2_db['ssl_ca'] }}" {%- endif %} - {% if icingaweb2_db['ssl_cert'] is defined %} --ssl-cert "{{ icingaweb2_db['ssl_cert'] }}" {%- endif %} - {% if icingaweb2_db['ssl_key'] is defined %} --ssl-key "{{ icingaweb2_db['ssl_key'] }}" {%- endif %} - {% if icingaweb2_db['ssl_cipher'] is defined %} --ssl-cipher "{{ icingaweb2_db['ssl_cipher'] }}" {%- endif %} - {% if icingaweb2_db['ssl_extra_options'] is defined %} {{ icingaweb2_db['ssl_extra_options'] }} {%- endif %} - -u "{{ icingaweb2_priv_db_user | default(icingaweb2_db['user']) }}" - -p"{{ icingaweb2_priv_db_password | default(icingaweb2_db['password']) }}" - "{{ icingaweb2_db['name'] }}" - - - name: MySQL check for icingaweb db schema - ansible.builtin.shell: > - {{ _tmp_mysqlcmd }} - -Ns -e "select * from icingaweb_user" - failed_when: false - changed_when: false - check_mode: false - register: _icingaweb2_db_schema - - - name: MySQL import icingaweb db schema - ansible.builtin.shell: > - {{ _tmp_mysqlcmd }} - < /usr/share/icingaweb2/schema/mysql.schema.sql - when: _icingaweb2_db_schema.rc != 0 - run_once: yes - when: icingaweb2_db_import_schema | default(False) - -- name: Ensure Icinga Web User - block: - - name: MySQL check for icingaweb db schema - ansible.builtin.shell: > - {{ _tmp_mysqlcmd }} - -Ns -e "select name from icingaweb_user where name like '{{ icingaweb2_admin_username }}'" - failed_when: false - changed_when: false - check_mode: false - register: _icingaweb2_db_user - - - name: Ensure admin user exists - ansible.builtin.shell: >- - echo "INSERT INTO icingaweb_user (name, active, password_hash) VALUES ('{{ icingaweb2_admin_username }}', 1, - '"`php -r 'echo password_hash("{{ icingaweb2_admin_password }}", PASSWORD_DEFAULT);'`"')" | {{ _tmp_mysqlcmd }} -Ns - when: _icingaweb2_db_user.stdout_lines | length <= 0 - run_once: yes - when: - - icingaweb2_admin_username is defined - - icingaweb2_admin_password is defined diff --git a/roles/icingaweb2/tasks/mysql/import_db.yml b/roles/icingaweb2/tasks/mysql/import_db.yml new file mode 100644 index 00000000..a647cb82 --- /dev/null +++ b/roles/icingaweb2/tasks/mysql/import_db.yml @@ -0,0 +1,17 @@ +--- + +- name: MySQL check for icingaweb db schema + ansible.builtin.shell: > + {{ _tmp_mysqlcmd }} + -Ns -e "select * from icingaweb_user" + failed_when: false + changed_when: false + check_mode: false + register: _icingaweb2_db_schema + +- name: MySQL import icingaweb db schema + ansible.builtin.shell: > + {{ _tmp_mysqlcmd }} + < /usr/share/icingaweb2/schema/mysql.schema.sql + when: _icingaweb2_db_schema.rc != 0 + run_once: yes \ No newline at end of file diff --git a/roles/icingaweb2/tasks/mysql/prepare_db.yml b/roles/icingaweb2/tasks/mysql/prepare_db.yml new file mode 100644 index 00000000..23d90973 --- /dev/null +++ b/roles/icingaweb2/tasks/mysql/prepare_db.yml @@ -0,0 +1,32 @@ +--- + +- name: check for admin user + block: + - name: Check Database Credentials + ansible.builtin.assert: + that: + - icingaweb2_db['user'] is defined + - icingaweb2_db['password'] is defined + fail_msg: "No database credentials defined. Please set icingaweb2_db. or a privileged user with icingaweb2_priv_db_" + when: icingaweb2_priv_db_password is undefined and icingaweb2_priv_db_user is undefined + + - name: Set db user with admin privileges + ansible.builtin.set_fact: + _priv_db_user: "{{ icingaweb2_priv_db_user }}" + _priv_db_pass: "{{ icingaweb2_priv_db_password }}" + when: icingaweb2_priv_db_password is defined and icingaweb2_priv_db_user is defined + +- name: prepare _tmp_mysqlcmd + ansible.builtin.set_fact: + _tmp_mysqlcmd: >- + mysql {% if icingaweb2_db['host'] | default('localhost') != 'localhost' %} -h "{{ icingaweb2_db['host'] }}" {%- endif %} + {% if icingaweb2_db['port'] is defined %} -P "{{ icingaweb2_db['port'] }}" {%- endif %} + {% if icingaweb2_db['ssl_mode'] is defined %} --ssl-mode "{{ icingaweb2_db['ssl_mode'] }}" {%- endif %} + {% if icingaweb2_db['ssl_ca'] is defined %} --ssl-ca "{{ icingaweb2_db['ssl_ca'] }}" {%- endif %} + {% if icingaweb2_db['ssl_cert'] is defined %} --ssl-cert "{{ icingaweb2_db['ssl_cert'] }}" {%- endif %} + {% if icingaweb2_db['ssl_key'] is defined %} --ssl-key "{{ icingaweb2_db['ssl_key'] }}" {%- endif %} + {% if icingaweb2_db['ssl_cipher'] is defined %} --ssl-cipher "{{ icingaweb2_db['ssl_cipher'] }}" {%- endif %} + {% if icingaweb2_db['ssl_extra_options'] is defined %} {{ icingaweb2_db['ssl_extra_options'] }} {%- endif %} + -u "{{ icingaweb2_priv_db_user | default(icingaweb2_db['user']) }}" + -p"{{ icingaweb2_priv_db_password | default(icingaweb2_db['password']) }}" + "{{ icingaweb2_db['name'] }}" \ No newline at end of file diff --git a/roles/icingaweb2/tasks/mysql/users_db.yml b/roles/icingaweb2/tasks/mysql/users_db.yml new file mode 100644 index 00000000..0a33d8d9 --- /dev/null +++ b/roles/icingaweb2/tasks/mysql/users_db.yml @@ -0,0 +1,30 @@ +--- + +- name: Check for user in icingaweb_user + ansible.builtin.shell: > + {{ _tmp_mysqlcmd }} + -Ns -e "select name from icingaweb_user where name='{{ _users.username }}'" + # failed_when: false + # changed_when: false + # check_mode: false + register: _icingaweb2_db_user + +- name: debug + debug: + var: + - _icingaweb2_db_user + +- name: Delete user if he exists + ansible.builtin.shell: > + {{ _tmp_mysqlcmd }} + -Ns -e "delete from icingaweb_user where name='{{ _users.username }}'" + when: _icingaweb2_db_user.stdout_lines | length >= 1 + register: user_deleted + +- name: Create User in icingaweb_user + ansible.builtin.shell: > + echo "INSERT INTO icingaweb_user + (name, active, password_hash) + VALUES ('{{ _users.username }}', 1, '"`php -r 'echo password_hash("{{ _users.password }}", PASSWORD_DEFAULT);'`"')" + | {{ _tmp_mysqlcmd }} -Ns + when: _icingaweb2_db_user.stdout_lines | length <= 0 or user_deleted.stdout_lines | length <= 0 \ No newline at end of file From 67c4b724b9166d0a3ccbb894a20e7c07f67eef46 Mon Sep 17 00:00:00 2001 From: losten Date: Fri, 24 Nov 2023 09:06:28 +0100 Subject: [PATCH 06/15] finished functionality for mysql --- roles/icingaweb2/tasks/manage_db.yml | 14 +++++-- roles/icingaweb2/tasks/mysql/users_db.yml | 48 +++++++++++++++-------- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/roles/icingaweb2/tasks/manage_db.yml b/roles/icingaweb2/tasks/manage_db.yml index 7b30f6bb..6ef162c3 100644 --- a/roles/icingaweb2/tasks/manage_db.yml +++ b/roles/icingaweb2/tasks/manage_db.yml @@ -8,10 +8,10 @@ ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/import_db.yml" when: icingaweb2_db_import_schema | default(False) -- name: add admin to users list +- name: add admin to users list when users exist ansible.builtin.set_fact: - icingaweb2_users: '{{ icingaweb2_users + [{"username": "{{ icingaweb2_admin_username }}", "password": "{{ icingaweb2_admin_password }}", "update": "{{ icingaweb2_admin_update | default(false) }}" }]}}' - when: icingaweb2_admin_username is defined and icingaweb2_admin_password is defined + icingaweb2_users: '{{ icingaweb2_users + [{"username": "{{ icingaweb2_admin_username }}", "password": "{{ icingaweb2_admin_password }}", "recreate": "{{ icingaweb2_admin_recreate is defined }}" }]}}' + when: icingaweb2_admin_username is defined and icingaweb2_admin_password is defined and icingaweb2_users is defined - name: add icinga web 2 users ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/users_db.yml" @@ -19,3 +19,11 @@ loop_control: loop_var: _users when: icingaweb2_users is defined + +- name: add icingaweb2 admin + ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/users_db.yml" + loop: + - { username: '{{ icingaweb2_admin_username }}', password: '{{ icingaweb2_admin_password }}', recreate: '{{ icingaweb2_admin_recreate is defined }}' } + loop_control: + loop_var: _users + when: icingaweb2_admin_username is defined and icingaweb2_admin_password and icingaweb2_users is undefined \ No newline at end of file diff --git a/roles/icingaweb2/tasks/mysql/users_db.yml b/roles/icingaweb2/tasks/mysql/users_db.yml index 0a33d8d9..240d6632 100644 --- a/roles/icingaweb2/tasks/mysql/users_db.yml +++ b/roles/icingaweb2/tasks/mysql/users_db.yml @@ -1,30 +1,44 @@ --- +- name: debug1 + debug: + msg: + - "{{ _users }}" + - name: Check for user in icingaweb_user ansible.builtin.shell: > {{ _tmp_mysqlcmd }} -Ns -e "select name from icingaweb_user where name='{{ _users.username }}'" - # failed_when: false - # changed_when: false - # check_mode: false + failed_when: false + changed_when: false + check_mode: false register: _icingaweb2_db_user -- name: debug - debug: - var: - - _icingaweb2_db_user - -- name: Delete user if he exists - ansible.builtin.shell: > - {{ _tmp_mysqlcmd }} - -Ns -e "delete from icingaweb_user where name='{{ _users.username }}'" - when: _icingaweb2_db_user.stdout_lines | length >= 1 - register: user_deleted +# - name: debug +# debug: +# msg: +# - "{{ _icingaweb2_db_user }}" -- name: Create User in icingaweb_user +- name: Create user in icingaweb or reset status to active or reset password ansible.builtin.shell: > echo "INSERT INTO icingaweb_user (name, active, password_hash) - VALUES ('{{ _users.username }}', 1, '"`php -r 'echo password_hash("{{ _users.password }}", PASSWORD_DEFAULT);'`"')" + VALUES ('{{ _users.username }}', 1, '"`php -r 'echo password_hash("{{ _users.password }}", PASSWORD_DEFAULT);'`"') + ON DUPLICATE KEY UPDATE active = 1, password_hash = '"`php -r 'echo password_hash("{{ _users.password }}", PASSWORD_DEFAULT);'`"'" | {{ _tmp_mysqlcmd }} -Ns - when: _icingaweb2_db_user.stdout_lines | length <= 0 or user_deleted.stdout_lines | length <= 0 \ No newline at end of file + when: _icingaweb2_db_user.stdout_lines | length <= 0 or _users.recreate is true + register: user_deleted + +# - name: debug condition +# debug: +# var: user_deleted + +# - name: Create User in icingaweb_user +# ansible.builtin.shell: > +# echo "INSERT INTO icingaweb_user +# (name, active, password_hash) +# VALUES ('{{ _users.username }}', 1, '"`php -r 'echo password_hash("{{ _users.password }}", PASSWORD_DEFAULT);'`"')" +# | {{ _tmp_mysqlcmd }} -Ns +# when: _icingaweb2_db_user.stdout_lines | length <= 0 + # or user_deleted.stdout_lines | length <= 0q + #(_icingaweb2_db_user.stdout_lines | length <= 0) or \ No newline at end of file From 7cf705cbfc4b1c2ce79faacd198572ed2664bfa7 Mon Sep 17 00:00:00 2001 From: Thilo W Date: Thu, 30 Nov 2023 09:53:42 +0100 Subject: [PATCH 07/15] Fix variable matching with ansible_lsb.id Ref #224 --- roles/repos/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/repos/tasks/main.yml b/roles/repos/tasks/main.yml index d0bd32d8..2cee1fe1 100644 --- a/roles/repos/tasks/main.yml +++ b/roles/repos/tasks/main.yml @@ -7,7 +7,7 @@ - "{{ ansible_os_family }}-{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml" - "{{ ansible_os_family }}-{{ ansible_distribution_major_version }}.yml" - "{{ ansible_os_family }}-{{ ansible_distribution }}.yml" - - "{{ ansible_os_family }}-{{ ansible_lsb.id }}.yml" + - "{{ ansible_os_family }}-{{ ansible_lsb.id if ansible_lsb.id is defined else ansible_distribution }}.yml" - "{{ ansible_os_family }}.yml" - default.yml paths: From 82f76f37e4600875ae33d30bc76d63a5854ebd21 Mon Sep 17 00:00:00 2001 From: Thilo W Date: Thu, 30 Nov 2023 17:11:03 +0100 Subject: [PATCH 08/15] add changelog --- CHANGELOG.rst | 12 ++++++++++-- changelogs/changelog.yaml | 9 +++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2ba6d5be..c76f6a46 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,13 +5,21 @@ Icinga.Icinga Release Notes .. contents:: Topics -v0.3.1 +v0.3.2 ====== Release Summary --------------- -This is a bugfix release +Bugfix Release + +Bugfixes +-------- + +- Role repos: Fix bug in variable search - thanks to @gianmarco-mameli #224 + +v0.3.1 +====== Major Changes ------------- diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 98f3c3c8..cda5e461 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -110,3 +110,12 @@ releases: - trivial_naming_tasks.yml - trivial_wrong_variable_name.yml release_date: '2023-11-21' + 0.3.2: + changes: + bugfixes: + - 'Role repos: Fix bug in variable search - thanks to @gianmarco-mameli #224' + release_summary: Bugfix Release + fragments: + - bugfix_variable_search.yml + - release.yml + release_date: '2023-11-30' From 94270c908989b6ee1a2d8a4ee5f6b30667e181d5 Mon Sep 17 00:00:00 2001 From: Thilo W Date: Thu, 30 Nov 2023 17:11:19 +0100 Subject: [PATCH 09/15] remove old fragments --- changelogs/fragments/feature_add_x509_module_installation.yml | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 changelogs/fragments/feature_add_x509_module_installation.yml diff --git a/changelogs/fragments/feature_add_x509_module_installation.yml b/changelogs/fragments/feature_add_x509_module_installation.yml deleted file mode 100644 index 82c1f981..00000000 --- a/changelogs/fragments/feature_add_x509_module_installation.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -major_changes: - - Added Installation of x509 certificate monitoring model From 2b3a42b634feac0a84ac7dc38eee6ba297d878dc Mon Sep 17 00:00:00 2001 From: Thilo W Date: Thu, 30 Nov 2023 17:12:14 +0100 Subject: [PATCH 10/15] bump to version 0.3.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 445591a3..d1d8d8fb 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: icinga name: icinga -version: 0.3.1 +version: 0.3.2 readme: README.md authors: - Lennart Betz From 86927e3fa28c90f41c4def6f4d415a13a2598e94 Mon Sep 17 00:00:00 2001 From: losten Date: Wed, 6 Dec 2023 12:43:10 +0100 Subject: [PATCH 11/15] added postgres compatibility --- roles/icingaweb2/tasks/main.yml | 2 +- roles/icingaweb2/tasks/mysql/users_db.yml | 24 ---------------- roles/icingaweb2/tasks/pgsql/import_db.yml | 17 +++++++++++ roles/icingaweb2/tasks/pgsql/prepare_db.yml | 31 +++++++++++++++++++++ roles/icingaweb2/tasks/pgsql/users_db.yml | 21 ++++++++++++++ 5 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 roles/icingaweb2/tasks/pgsql/import_db.yml create mode 100644 roles/icingaweb2/tasks/pgsql/prepare_db.yml create mode 100644 roles/icingaweb2/tasks/pgsql/users_db.yml diff --git a/roles/icingaweb2/tasks/main.yml b/roles/icingaweb2/tasks/main.yml index 1a53be57..f587a9a2 100644 --- a/roles/icingaweb2/tasks/main.yml +++ b/roles/icingaweb2/tasks/main.yml @@ -26,7 +26,7 @@ - name: Manage Icinga Web 2 DB ansible.builtin.include_tasks: "manage_db.yml" - when: icingaweb2_db is defined and (icingaweb2_db_import_schema | default(False) or icingaweb2_users is defined or icingaweb2_admin is defined) + when: icingaweb2_db is defined and (icingaweb2_db_import_schema | default(False) or icingaweb2_users is defined or icingaweb2_admin_username is defined) - name: Configure modules ansible.builtin.include_tasks: "modules/{{ item.key }}.yml" diff --git a/roles/icingaweb2/tasks/mysql/users_db.yml b/roles/icingaweb2/tasks/mysql/users_db.yml index 240d6632..ee77f5cd 100644 --- a/roles/icingaweb2/tasks/mysql/users_db.yml +++ b/roles/icingaweb2/tasks/mysql/users_db.yml @@ -1,10 +1,5 @@ --- -- name: debug1 - debug: - msg: - - "{{ _users }}" - - name: Check for user in icingaweb_user ansible.builtin.shell: > {{ _tmp_mysqlcmd }} @@ -14,11 +9,6 @@ check_mode: false register: _icingaweb2_db_user -# - name: debug -# debug: -# msg: -# - "{{ _icingaweb2_db_user }}" - - name: Create user in icingaweb or reset status to active or reset password ansible.builtin.shell: > echo "INSERT INTO icingaweb_user @@ -28,17 +18,3 @@ | {{ _tmp_mysqlcmd }} -Ns when: _icingaweb2_db_user.stdout_lines | length <= 0 or _users.recreate is true register: user_deleted - -# - name: debug condition -# debug: -# var: user_deleted - -# - name: Create User in icingaweb_user -# ansible.builtin.shell: > -# echo "INSERT INTO icingaweb_user -# (name, active, password_hash) -# VALUES ('{{ _users.username }}', 1, '"`php -r 'echo password_hash("{{ _users.password }}", PASSWORD_DEFAULT);'`"')" -# | {{ _tmp_mysqlcmd }} -Ns -# when: _icingaweb2_db_user.stdout_lines | length <= 0 - # or user_deleted.stdout_lines | length <= 0q - #(_icingaweb2_db_user.stdout_lines | length <= 0) or \ No newline at end of file diff --git a/roles/icingaweb2/tasks/pgsql/import_db.yml b/roles/icingaweb2/tasks/pgsql/import_db.yml new file mode 100644 index 00000000..1d5aa10f --- /dev/null +++ b/roles/icingaweb2/tasks/pgsql/import_db.yml @@ -0,0 +1,17 @@ +--- + +- name: PostgreSQL check for icingaweb db schema + ansible.builtin.shell: > + {{ _tmp_pgsqlcmd }} + -w -c "select * from icingaweb_user" + failed_when: false + changed_when: false + check_mode: false + register: _icingaweb2_db_schema + +- name: PostgreSQL import icingaweb db schema + ansible.builtin.shell: > + {{ _tmp_pgsqlcmd }} + -w -f /usr/share/icingaweb2/schema/pgsql.schema.sql + when: _icingaweb2_db_schema.rc != 0 + run_once: yes \ No newline at end of file diff --git a/roles/icingaweb2/tasks/pgsql/prepare_db.yml b/roles/icingaweb2/tasks/pgsql/prepare_db.yml new file mode 100644 index 00000000..7012d935 --- /dev/null +++ b/roles/icingaweb2/tasks/pgsql/prepare_db.yml @@ -0,0 +1,31 @@ +--- + +- name: check for admin user + block: + - name: Check Database Credentials + ansible.builtin.assert: + that: + - icingaweb2_db['user'] is defined + - icingaweb2_db['password'] is defined + fail_msg: "No database credentials defined. Please set icingaweb2_db. or a privileged user with icingaweb2_priv_db_" + when: icingaweb2_priv_db_password is undefined and icingaweb2_priv_db_user is undefined + + - name: Set db user with admin privileges + ansible.builtin.set_fact: + _priv_db_user: "{{ icingaweb2_priv_db_user }}" + _priv_db_pass: "{{ icingaweb2_priv_db_password }}" + when: icingaweb2_priv_db_password is defined and icingaweb2_priv_db_user is defined + +- name: Build psql command + ansible.builtin.set_fact: + _tmp_pgsqlcmd: >- + PGPASSWORD="{{ icingaweb2_priv_db_password | default(icingaweb2_db['password']) }}" + psql + "host={{ icingaweb2_db['host'] }} + {% if icingaweb2_db['port'] is defined %} port={{ icingaweb2_db['port'] }} {%- endif %} + user={{ icingaweb2_priv_db_user | default(icingaweb2_db['user']) }} + dbname={{ icingaweb2_db['name'] }} + {% if icingaweb2_db['ssl_mode'] is defined %} sslmode={{ icingaweb2_db['ssl_mode'] | default('require') }} {%- endif %} + {% if icingaweb2_db['ssl_cert'] is defined %} sslcert={{ icingaweb2_db['ssl_cert'] }} {%- endif %} + {% if icingaweb2_db['ssl_key'] is defined %} sslkey={{ icingaweb2_db['ssl_key'] }} {%- endif %} + {% if icingaweb2_db['ssl_extra_options'] is defined %} {{ icingaweb2_db['ssl_extra_options'] }} {%- endif %}" diff --git a/roles/icingaweb2/tasks/pgsql/users_db.yml b/roles/icingaweb2/tasks/pgsql/users_db.yml new file mode 100644 index 00000000..6e42200d --- /dev/null +++ b/roles/icingaweb2/tasks/pgsql/users_db.yml @@ -0,0 +1,21 @@ +--- + +- name: PostgreSQL check for icingaweb admin user + ansible.builtin.shell: > + {{ _tmp_pgsqlcmd }} + -w -c "select name from icingaweb_user where name like '{{ _users.username }}'" + failed_when: false + changed_when: false + check_mode: false + register: _icingaweb2_db_user + +- name: Create user in icingaweb or reset status to active or reset password + ansible.builtin.shell: > + echo "INSERT INTO icingaweb_user + (name, active, password_hash) + VALUES ('{{ _users.username }}', 1, '"`php -r 'echo password_hash("{{ _users.password }}", PASSWORD_DEFAULT);'`"') + ON CONFLICT (name) DO UPDATE + SET active = 1, password_hash = '"`php -r 'echo password_hash("{{ _users.password }}", PASSWORD_DEFAULT);'`"'" + | {{ _tmp_pgsqlcmd }} -w + when: _icingaweb2_db_user.stdout == " name \n------\n(0 rows)" or _users.recreate is true + register: user_deleted \ No newline at end of file From aa262022dd8d43f9ab4955afdbedee6732c1a363 Mon Sep 17 00:00:00 2001 From: losten Date: Wed, 6 Dec 2023 12:54:50 +0100 Subject: [PATCH 12/15] Cleanup task names and delete unnecessery files --- roles/icingaweb2/tasks/manage_db.yml | 10 +-- .../tasks/manage_icingaweb_pgsql_db.yml | 63 ------------------- .../icingaweb2/tasks/manage_mysql_imports.yml | 38 ----------- roles/icingaweb2/tasks/mysql/prepare_db.yml | 4 +- roles/icingaweb2/tasks/pgsql/prepare_db.yml | 4 +- 5 files changed, 9 insertions(+), 110 deletions(-) delete mode 100644 roles/icingaweb2/tasks/manage_icingaweb_pgsql_db.yml delete mode 100644 roles/icingaweb2/tasks/manage_mysql_imports.yml diff --git a/roles/icingaweb2/tasks/manage_db.yml b/roles/icingaweb2/tasks/manage_db.yml index 6ef162c3..e3180945 100644 --- a/roles/icingaweb2/tasks/manage_db.yml +++ b/roles/icingaweb2/tasks/manage_db.yml @@ -1,26 +1,26 @@ --- -- name: prepare database +- name: Prepare database ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/prepare_db.yml" when: icingaweb2_db is defined -- name: import database schema +- name: Import database schema ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/import_db.yml" when: icingaweb2_db_import_schema | default(False) -- name: add admin to users list when users exist +- name: Add admin to users list when users is defined ansible.builtin.set_fact: icingaweb2_users: '{{ icingaweb2_users + [{"username": "{{ icingaweb2_admin_username }}", "password": "{{ icingaweb2_admin_password }}", "recreate": "{{ icingaweb2_admin_recreate is defined }}" }]}}' when: icingaweb2_admin_username is defined and icingaweb2_admin_password is defined and icingaweb2_users is defined -- name: add icinga web 2 users +- name: Add Icinga web 2 users ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/users_db.yml" loop: "{{ icingaweb2_users }}" loop_control: loop_var: _users when: icingaweb2_users is defined -- name: add icingaweb2 admin +- name: Add Icingaweb2 admin ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/users_db.yml" loop: - { username: '{{ icingaweb2_admin_username }}', password: '{{ icingaweb2_admin_password }}', recreate: '{{ icingaweb2_admin_recreate is defined }}' } diff --git a/roles/icingaweb2/tasks/manage_icingaweb_pgsql_db.yml b/roles/icingaweb2/tasks/manage_icingaweb_pgsql_db.yml deleted file mode 100644 index 44c7252f..00000000 --- a/roles/icingaweb2/tasks/manage_icingaweb_pgsql_db.yml +++ /dev/null @@ -1,63 +0,0 @@ ---- - -- name: Check Database Credentials - ansible.builtin.assert: - that: - - icingaweb2_db['user'] is defined - - icingaweb2_db['password'] is defined - fail_msg: "No database credentials defined. Please set icingaweb2_db. or a privileged user with icingaweb2_priv_db_" - when: icingaweb2_priv_db_password is undefined and icingaweb2_priv_db_user is undefined - -- name: PostgreSQL import IDO schema - block: - - name: Build psql command - ansible.builtin.set_fact: - _tmp_pgsqlcmd: >- - PGPASSWORD="{{ icingaweb2_priv_db_password | default(icingaweb2_db['password']) }}" - psql - "host={{ icingaweb2_db['host'] }} - {% if icingaweb2_db['port'] is defined %} port={{ icingaweb2_db['port'] }} {%- endif %} - user={{ icingaweb2_priv_db_user | default(icingaweb2_db['user']) }} - dbname={{ icingaweb2_db['name'] }} - {% if icingaweb2_db['ssl_mode'] is defined %} sslmode={{ icingaweb2_db['ssl_mode'] | default('require') }} {%- endif %} - {% if icingaweb2_db['ssl_cert'] is defined %} sslcert={{ icingaweb2_db['ssl_cert'] }} {%- endif %} - {% if icingaweb2_db['ssl_key'] is defined %} sslkey={{ icingaweb2_db['ssl_key'] }} {%- endif %} - {% if icingaweb2_db['ssl_extra_options'] is defined %} {{ icingaweb2_db['ssl_extra_options'] }} {%- endif %}" - - - name: PostgreSQL check for IDO schema - ansible.builtin.shell: > - {{ _tmp_pgsqlcmd }} - -w -c "select * from icingaweb_user" - failed_when: false - changed_when: false - check_mode: false - register: _icingaweb2_db_schema - - - name: PostgreSQL import IDO schema - ansible.builtin.shell: > - {{ _tmp_pgsqlcmd }} - -w -f /usr/share/icingaweb2/schema/pgsql.schema.sql - when: _icingaweb2_db_schema.rc != 0 - run_once: yes - when: icingaweb2_db_import_schema | default(False) - -- name: Ensure Icinga Web User - block: - - name: PostgreSQL check for icingaweb admin user - ansible.builtin.shell: > - {{ _tmp_pgsqlcmd }} - -w -c "select name from icingaweb_user where name like '{{ icingaweb2_admin_username }}'" - failed_when: false - changed_when: false - check_mode: false - register: _icingaweb2_db_user - - - name: Ensure admin user exists - ansible.builtin.shell: >- - echo "INSERT INTO icingaweb_user (name, active, password_hash) VALUES ('{{ icingaweb2_admin_username }}', 1, - '"`php -r 'echo password_hash("{{ icingaweb2_admin_password }}", PASSWORD_DEFAULT);'`"')" | {{ _tmp_pgsqlcmd }} -w - when: '"(0 rows)" in _icingaweb2_db_user.stdout_lines' - run_once: yes - when: - - icingaweb2_admin_username is defined - - icingaweb2_admin_password is defined diff --git a/roles/icingaweb2/tasks/manage_mysql_imports.yml b/roles/icingaweb2/tasks/manage_mysql_imports.yml deleted file mode 100644 index 676c6df2..00000000 --- a/roles/icingaweb2/tasks/manage_mysql_imports.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -- name: Check Database Credentials - ansible.builtin.assert: - that: - - _db['user'] is defined - - _db['password'] is defined - fail_msg: "No database credentials defined." - -- name: Build mysql command - ansible.builtin.set_fact: - _tmp_mysqlcmd: >- - mysql {% if _db['host'] | default('localhost') != 'localhost' %} -h "{{ _db['host'] }}" {%- endif %} - {% if _db['port'] is defined %} -P "{{ _db['port'] }}" {%- endif %} - {% if _db['ssl_mode'] is defined %} --ssl-mode "{{ _db['ssl_mode'] }}" {%- endif %} - {% if _db['ssl_ca'] is defined %} --ssl-ca "{{ _db['ssl_ca'] }}" {%- endif %} - {% if _db['ssl_cert'] is defined %} --ssl-cert "{{ _db['ssl_cert'] }}" {%- endif %} - {% if _db['ssl_key'] is defined %} --ssl-key "{{ _db['ssl_key'] }}" {%- endif %} - {% if _db['ssl_cipher'] is defined %} --ssl-cipher "{{ _db['ssl_cipher'] }}" {%- endif %} - {% if _db['ssl_extra_options'] is defined %} {{ _db['ssl_extra_options'] }} {%- endif %} - -u "{{ _db['user'] }}" - -p"{{ _db['password'] }}" - "{{ _db['name'] }}" - -- name: MySQL check for db schema - ansible.builtin.shell: > - {{ _tmp_mysqlcmd }} - -Ns -e "{{ _db['select_query'] }}" - failed_when: false - changed_when: false - check_mode: false - register: _db_schema - -- name: MySQL import db schema - ansible.builtin.shell: > - {{ _tmp_mysqlcmd }} - < {{ _db['schema_path'] }} - when: _db_schema.rc != 0 - run_once: yes diff --git a/roles/icingaweb2/tasks/mysql/prepare_db.yml b/roles/icingaweb2/tasks/mysql/prepare_db.yml index 23d90973..840182ad 100644 --- a/roles/icingaweb2/tasks/mysql/prepare_db.yml +++ b/roles/icingaweb2/tasks/mysql/prepare_db.yml @@ -1,6 +1,6 @@ --- -- name: check for admin user +- name: Check for admin user block: - name: Check Database Credentials ansible.builtin.assert: @@ -16,7 +16,7 @@ _priv_db_pass: "{{ icingaweb2_priv_db_password }}" when: icingaweb2_priv_db_password is defined and icingaweb2_priv_db_user is defined -- name: prepare _tmp_mysqlcmd +- name: Prepare mysql command ansible.builtin.set_fact: _tmp_mysqlcmd: >- mysql {% if icingaweb2_db['host'] | default('localhost') != 'localhost' %} -h "{{ icingaweb2_db['host'] }}" {%- endif %} diff --git a/roles/icingaweb2/tasks/pgsql/prepare_db.yml b/roles/icingaweb2/tasks/pgsql/prepare_db.yml index 7012d935..6d4cef75 100644 --- a/roles/icingaweb2/tasks/pgsql/prepare_db.yml +++ b/roles/icingaweb2/tasks/pgsql/prepare_db.yml @@ -1,6 +1,6 @@ --- -- name: check for admin user +- name: Check for admin user block: - name: Check Database Credentials ansible.builtin.assert: @@ -16,7 +16,7 @@ _priv_db_pass: "{{ icingaweb2_priv_db_password }}" when: icingaweb2_priv_db_password is defined and icingaweb2_priv_db_user is defined -- name: Build psql command +- name: Prepare psql command ansible.builtin.set_fact: _tmp_pgsqlcmd: >- PGPASSWORD="{{ icingaweb2_priv_db_password | default(icingaweb2_db['password']) }}" From 8354e845e7147e382f7c8e9397a868d7f725f8f0 Mon Sep 17 00:00:00 2001 From: losten Date: Wed, 6 Dec 2023 15:27:19 +0100 Subject: [PATCH 13/15] added documentation and fragment to feature --- .../fragments/feature-add-icingaweb2-users.yml | 3 +++ doc/role-icingaweb2/role-icingaweb2.md | 14 +++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/feature-add-icingaweb2-users.yml diff --git a/changelogs/fragments/feature-add-icingaweb2-users.yml b/changelogs/fragments/feature-add-icingaweb2-users.yml new file mode 100644 index 00000000..9e4b2174 --- /dev/null +++ b/changelogs/fragments/feature-add-icingaweb2-users.yml @@ -0,0 +1,3 @@ +--- +minor_changes: + - Added the ability to create additional Icinga Web 2 users \ No newline at end of file diff --git a/doc/role-icingaweb2/role-icingaweb2.md b/doc/role-icingaweb2/role-icingaweb2.md index bff00b7c..63cddbfa 100644 --- a/doc/role-icingaweb2/role-icingaweb2.md +++ b/doc/role-icingaweb2/role-icingaweb2.md @@ -29,8 +29,20 @@ icingaweb2_db: * `icingaweb2_db_import_schema: boolean` * Decides whether the schema should be imported in the database defined at `icingaweb2_db`. **Default: False** -* `icingaweb2_admin_: string` +* `icingaweb2_admin_: string` * Set the username and password for the first admin user for Icinga Web 2. + * Recreate can be used to change password of admin. **Default:False** + +In addition to the Icinga Web 2 Admin, other users can be configured by defining `icingaweb2_users`. +The `recreate` parameter can be used to change passwords or to enable the user if he has been disabled. **Default: False** +``` + icingaweb2_users: + - username: 'foo' + password: 'bar' + recreate: true + - username: webadmin + [...] +``` #### Resources From 928632556717c2754e8be4e533bec9202ef1e733 Mon Sep 17 00:00:00 2001 From: losten Date: Wed, 6 Dec 2023 15:27:41 +0100 Subject: [PATCH 14/15] addjusted test to match new feature --- molecule/default/converge.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index d3b3194a..1f5a3574 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -9,7 +9,11 @@ host: 127.0.0.1 user: icingaweb password: icingaweb - icingaweb2_database_import_schema: false + icingaweb2_database_import_schema: true + icingaweb2_users: + - username: webadmin + password: webadmin + recreate: false icingadb_database_import_schema: false mysql_innodb_file_format: barracuda mysql_innodb_large_prefix: 1 @@ -83,8 +87,8 @@ pre_tasks: - ansible.builtin.include_role: name: repos - # - ansible.builtin.include_role: - # name: geerlingguy.mysql + - ansible.builtin.include_role: + name: geerlingguy.mysql - ansible.builtin.include_role: name: icinga2 - ansible.builtin.include_role: From 2f327c55197a0a2db6c5e3ed314721587a142a47 Mon Sep 17 00:00:00 2001 From: losten Date: Thu, 7 Dec 2023 14:17:18 +0100 Subject: [PATCH 15/15] optimized feature as suggested by maintainer --- doc/role-icingaweb2/role-icingaweb2.md | 4 +++- roles/icingaweb2/defaults/main.yml | 2 ++ roles/icingaweb2/tasks/manage_db.yml | 16 ++++------------ roles/icingaweb2/tasks/mysql/users_db.yml | 1 + roles/icingaweb2/tasks/pgsql/users_db.yml | 3 ++- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/doc/role-icingaweb2/role-icingaweb2.md b/doc/role-icingaweb2/role-icingaweb2.md index 63cddbfa..8e74fe0e 100644 --- a/doc/role-icingaweb2/role-icingaweb2.md +++ b/doc/role-icingaweb2/role-icingaweb2.md @@ -29,8 +29,10 @@ icingaweb2_db: * `icingaweb2_db_import_schema: boolean` * Decides whether the schema should be imported in the database defined at `icingaweb2_db`. **Default: False** -* `icingaweb2_admin_: string` +* `icingaweb2_admin_: string` * Set the username and password for the first admin user for Icinga Web 2. + +* `icingaweb2_admin_recreate: boolean` * Recreate can be used to change password of admin. **Default:False** In addition to the Icinga Web 2 Admin, other users can be configured by defining `icingaweb2_users`. diff --git a/roles/icingaweb2/defaults/main.yml b/roles/icingaweb2/defaults/main.yml index 089e7256..8eb20b47 100644 --- a/roles/icingaweb2/defaults/main.yml +++ b/roles/icingaweb2/defaults/main.yml @@ -38,3 +38,5 @@ icingaweb2_config: themes: default: Icinga icingaweb2_cli: icingacli + +icingaweb2_users: [] diff --git a/roles/icingaweb2/tasks/manage_db.yml b/roles/icingaweb2/tasks/manage_db.yml index e3180945..13a00269 100644 --- a/roles/icingaweb2/tasks/manage_db.yml +++ b/roles/icingaweb2/tasks/manage_db.yml @@ -8,22 +8,14 @@ ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/import_db.yml" when: icingaweb2_db_import_schema | default(False) -- name: Add admin to users list when users is defined +- name: Add admin to users list ansible.builtin.set_fact: - icingaweb2_users: '{{ icingaweb2_users + [{"username": "{{ icingaweb2_admin_username }}", "password": "{{ icingaweb2_admin_password }}", "recreate": "{{ icingaweb2_admin_recreate is defined }}" }]}}' - when: icingaweb2_admin_username is defined and icingaweb2_admin_password is defined and icingaweb2_users is defined + icingaweb2_users: '{{ icingaweb2_users + [{"username": "{{ icingaweb2_admin_username }}", "password": "{{ icingaweb2_admin_password }}", "recreate": "{{ icingaweb2_admin_recreate | default(False) }}" }]}}' + when: icingaweb2_admin_username is defined and icingaweb2_admin_password is defined - name: Add Icinga web 2 users ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/users_db.yml" loop: "{{ icingaweb2_users }}" loop_control: loop_var: _users - when: icingaweb2_users is defined - -- name: Add Icingaweb2 admin - ansible.builtin.include_tasks: "{{ icingaweb2_db.type }}/users_db.yml" - loop: - - { username: '{{ icingaweb2_admin_username }}', password: '{{ icingaweb2_admin_password }}', recreate: '{{ icingaweb2_admin_recreate is defined }}' } - loop_control: - loop_var: _users - when: icingaweb2_admin_username is defined and icingaweb2_admin_password and icingaweb2_users is undefined \ No newline at end of file + when: icingaweb2_users | length > 0 diff --git a/roles/icingaweb2/tasks/mysql/users_db.yml b/roles/icingaweb2/tasks/mysql/users_db.yml index ee77f5cd..87a03567 100644 --- a/roles/icingaweb2/tasks/mysql/users_db.yml +++ b/roles/icingaweb2/tasks/mysql/users_db.yml @@ -17,4 +17,5 @@ ON DUPLICATE KEY UPDATE active = 1, password_hash = '"`php -r 'echo password_hash("{{ _users.password }}", PASSWORD_DEFAULT);'`"'" | {{ _tmp_mysqlcmd }} -Ns when: _icingaweb2_db_user.stdout_lines | length <= 0 or _users.recreate is true + run_once: true register: user_deleted diff --git a/roles/icingaweb2/tasks/pgsql/users_db.yml b/roles/icingaweb2/tasks/pgsql/users_db.yml index 6e42200d..dfd4e2f6 100644 --- a/roles/icingaweb2/tasks/pgsql/users_db.yml +++ b/roles/icingaweb2/tasks/pgsql/users_db.yml @@ -18,4 +18,5 @@ SET active = 1, password_hash = '"`php -r 'echo password_hash("{{ _users.password }}", PASSWORD_DEFAULT);'`"'" | {{ _tmp_pgsqlcmd }} -w when: _icingaweb2_db_user.stdout == " name \n------\n(0 rows)" or _users.recreate is true - register: user_deleted \ No newline at end of file + run_once: true + register: user_deleted