diff --git a/changelogs/fragments/feature_kubernetes.yml b/changelogs/fragments/feature_kubernetes.yml new file mode 100644 index 00000000..4e09589f --- /dev/null +++ b/changelogs/fragments/feature_kubernetes.yml @@ -0,0 +1,4 @@ +--- +major_changes: + - Add a role for the installation and configuration of `Icinga for Kubernetes `_. + - Add tasks to role :code:`icingaweb2` to install and configure `Icinga for Kubernetes Web `_. \ No newline at end of file diff --git a/doc/role-icinga_kubernetes/role-icinga_kubernetes.md b/doc/role-icinga_kubernetes/role-icinga_kubernetes.md new file mode 100644 index 00000000..70c0a894 --- /dev/null +++ b/doc/role-icinga_kubernetes/role-icinga_kubernetes.md @@ -0,0 +1,75 @@ +# Role icinga.icinga.icinga_kubernetes + +This role installs and configures the Icinga Kubernetes Daemon. In addition it can also import the schema into the database. +More information about this package can be found [in the official documentation](https://icinga.com/docs/icinga-for-kubernetes/latest/doc/01-About/). + +## Database + +Icinga Kubernetes 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 + +The following variables define the configuration for Icinga Kubernetes. Some variables got predefined [defaults](../../roles/kubernetes/defaults/main.yml), others are purely opt-in. + +For more information on the respective settings please see [the official documentation](https://icinga.com/docs/icinga-for-kubernetes/latest/doc/03-Configuration/). + +### Database Configuration + +| Variable | Type | Description | Default | +|----------|------|-------------|---------| +| `icinga_kubernetes_database_host` | `String` | Defines database address to connect to. | `127.0.0.1` | +| `icinga_kubernetes_database_import_schema` | `bool` | Defines whether to import the schema into the database or not. **Needs `icinga_kubernetes_database_type` to be set**. | `false` | +| `icinga_kubernetes_database_name` | `String` | Defines the database to connect to. | `kubernetes` | +| `icinga_kubernetes_database_password` | `String` | Defines the database password to connect with. | `kubernetes` | +| `icinga_kubernetes_database_port` | `int` | Defines the database port to connect to. | **n/a** | +| `icinga_kubernetes_database_type` | `mysql` | Defines database type set in `config.yml`. | `mysql` | +| `icinga_kubernetes_database_user` | `String` | Defines database user set in `config.yml`. | `kubernetes` | + +### Icinga Kubernetes Configuration + +The following variables are used for the Icinga Kubernetes setup. Normally, you can rely on the defaults to work and should **not** change them unless you know what you are doing. + +| Variable | Type | Description | Default | +|----------|------|-------------|---------| +| `icinga_kubernetes_config_dir` | `String` | Defines the directory where the Icinga Kubernetes configuration is stored. | `/etc/icinga-kubernetes` | +| `icinga_kubernetes_database_schema` | `String` | Defines the path to the schema file. | `"/usr/share/icinga-kubernetes/schema/{{ icinga_kubernetes_database_type }}/schema.sql"` | +| `icinga_kubernetes_group` | `String` | Defines the group membership for the Icinga Kubernetes user. | `icinga-kubernetes` | +| `icinga_kubernetes_packages` | `List` | Defines the packages to install for Icinga Kubernetes. | `[icinga-kubernetes]` | +| `icinga_kubernetes_service_name` | `String` | Defines the name of the Icinga Kubernetes service. | `icinga-kubernetes` | +| `icinga_kubernetes_user` | `String` | Defines the user for the Icinga Kubernetes service. | `icinga-kubernetes` | +| `icinga_kubernetes_kubeconfig_path` | `String` | Defines the path for the kubeconfig file, if not in standard path defined by KUBECONFIG env | | + +## Examples + +This play installs Icinga Kubernetes with on the same host as its connected MySQL database. It also imports the schema into the database. + +```yaml +- name: Install Icinga Kubernetes + hosts: icingakubernetes + become: true + vars: + icinga_kubernetes_database_import_schema: true # Import the schema into the database + icinga_kubernetes_database_type: mysql # needed by the schema import + + roles: + - role: icinga.icinga.icinga_kubernetes +``` + +This example installs Icinga Kubernetes and connects it to a **remote** MySQL database. It also imports the schema into the database and set a custom kubeconfig path. + +```yaml +- name: Install Icinga Kubernetes + hosts: icingadb + become: true + vars: + icinga_kubernetes_database_type: mysql + icinga_kubernetes_database_host: mysql.example.com + icinga_kubernetes_database_port: 3306 + icinga_kubernetes_database_user: kube_user + icinga_kubernetes_database_password: hellokube$123 + icinga_kubernetes_database_import_schema: true + icinga_kubernetes_kubeconfig_path: /opt/kube/config + + roles: + - role: icinga.icinga.icinga_kubernetes +``` diff --git a/doc/role-icingaweb2/module-kubernetes.md b/doc/role-icingaweb2/module-kubernetes.md new file mode 100644 index 00000000..77876512 --- /dev/null +++ b/doc/role-icingaweb2/module-kubernetes.md @@ -0,0 +1,24 @@ +## Module Kubernetes + +### 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. + +```yaml +icingaweb2_modules: + kubernetes: + enabled: true + source: package + config: + database: + resource: kubernetes_db +``` diff --git a/roles/icinga_kubernetes/defaults/main.yml b/roles/icinga_kubernetes/defaults/main.yml new file mode 100644 index 00000000..aec56976 --- /dev/null +++ b/roles/icinga_kubernetes/defaults/main.yml @@ -0,0 +1,19 @@ +--- +# Database Settings +icinga_kubernetes_database_import_schema: false +icinga_kubernetes_database_type: mysql +icinga_kubernetes_database_host: 127.0.0.1 +icinga_kubernetes_database_name: kubernetes +icinga_kubernetes_database_user: kubernetes +icinga_kubernetes_database_password: kubernetes +# icinga_kubernetes_database_port: + +# Variables for kubernetes role +icinga_kubernetes_config_dir: /etc/icinga-kubernetes +icinga_kubernetes_service_name: icinga-kubernetes +icinga_kubernetes_group: icinga-kubernetes +icinga_kubernetes_user: icinga-kubernetes +icinga_kubernetes_database_schema: "/usr/share/icinga-kubernetes/schema/{{ icinga_kubernetes_database_type }}/schema.sql" +icinga_kubernetes_packages: + - icinga-kubernetes +# icinga_kubernetes_kubeconfig_path: diff --git a/roles/icinga_kubernetes/handlers/main.yml b/roles/icinga_kubernetes/handlers/main.yml new file mode 100644 index 00000000..f7630776 --- /dev/null +++ b/roles/icinga_kubernetes/handlers/main.yml @@ -0,0 +1,9 @@ +--- +- name: Systemd reload + ansible.builtin.systemd: + daemon_reload: true + +- name: Kubernetes-restart + ansible.builtin.service: + name: "{{ icinga_kubernetes_service_name }}" + state: restarted diff --git a/roles/icinga_kubernetes/meta/main.yml b/roles/icinga_kubernetes/meta/main.yml new file mode 100644 index 00000000..1b6cbe3a --- /dev/null +++ b/roles/icinga_kubernetes/meta/main.yml @@ -0,0 +1,27 @@ +galaxy_info: + author: | + - Gianmarco Mameli + description: Role to install, configure or manage Icinga Kubernetes. + license: Apache-2.0 + min_ansible_version: '2.9' + platforms: + - name: opensuse + versions: ['15.5'] + - name: SLES + versions: ['15'] + - name: EL + versions: ['7'] + - name: Debian + versions: ['buster','bullseye','bookworm'] + - name: Ubuntu + versions: ['jammy'] + galaxy_tags: + - icinga + - monitoring + - satellite + - agent + - server + - master + - icinga2 + - kubernetes +dependencies: [] diff --git a/roles/icinga_kubernetes/tasks/install_on_debian.yml b/roles/icinga_kubernetes/tasks/install_on_debian.yml new file mode 100644 index 00000000..a47970ea --- /dev/null +++ b/roles/icinga_kubernetes/tasks/install_on_debian.yml @@ -0,0 +1,4 @@ +- name: Debian - Install Kubernetes packages + ansible.builtin.apt: + name: "{{ icinga_kubernetes_packages }}" + state: present diff --git a/roles/icinga_kubernetes/tasks/install_on_redhat.yml b/roles/icinga_kubernetes/tasks/install_on_redhat.yml new file mode 100644 index 00000000..ffa86a8c --- /dev/null +++ b/roles/icinga_kubernetes/tasks/install_on_redhat.yml @@ -0,0 +1,4 @@ +- name: RedHat - Install Kubernetes packages + ansible.builtin.yum: + name: "{{ icinga_kubernetes_packages }}" + state: present diff --git a/roles/icinga_kubernetes/tasks/install_on_suse.yml b/roles/icinga_kubernetes/tasks/install_on_suse.yml new file mode 100644 index 00000000..405e52a2 --- /dev/null +++ b/roles/icinga_kubernetes/tasks/install_on_suse.yml @@ -0,0 +1,4 @@ +- name: Suse - Install Kubernetes packages + community.general.zypper: + name: "{{ icinga_kubernetes_packages }}" + state: present diff --git a/roles/icinga_kubernetes/tasks/main.yml b/roles/icinga_kubernetes/tasks/main.yml new file mode 100644 index 00000000..119f8c09 --- /dev/null +++ b/roles/icinga_kubernetes/tasks/main.yml @@ -0,0 +1,32 @@ +--- +- name: Include OS specific vars + ansible.builtin.include_vars: "{{ lookup('first_found', params) }}" + vars: + params: + files: + - "{{ 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 }}.yml" + - default.yml + paths: + - "{{ role_path }}/vars" + +- name: Check supported operatingsystems + block: + - name: Include OS specific installation + ansible.builtin.include_tasks: "install_on_{{ ansible_os_family | lower }}.yml" + rescue: + - name: "OS family not supported!" + ansible.builtin.fail: + msg: "The OS {{ ansible_os_family }} is not supported!" + +- name: Include Tasks to configure Icinga Kubernetes + ansible.builtin.include_tasks: manage_config.yml + +- name: Include Tasks to import DB Schema + ansible.builtin.include_tasks: "manage_schema_{{ icinga_kubernetes_database_type | lower }}.yml" + when: icinga_kubernetes_database_import_schema and icinga_kubernetes_database_type is defined + +- name: Include Tasks to manage Kubernetes Service + ansible.builtin.include_tasks: manage_service.yml diff --git a/roles/icinga_kubernetes/tasks/manage_config.yml b/roles/icinga_kubernetes/tasks/manage_config.yml new file mode 100644 index 00000000..5da34111 --- /dev/null +++ b/roles/icinga_kubernetes/tasks/manage_config.yml @@ -0,0 +1,9 @@ +--- +- name: Write configuration to {{ icinga_kubernetes_config_dir }}/config.yml + ansible.builtin.template: + src: kubernetes.yml.j2 + dest: "{{ icinga_kubernetes_config_dir }}/config.yml" + owner: "{{ icinga_kubernetes_user }}" + group: "{{ icinga_kubernetes_group }}" + mode: 0640 + notify: Kubernetes-restart diff --git a/roles/icinga_kubernetes/tasks/manage_schema_mysql.yml b/roles/icinga_kubernetes/tasks/manage_schema_mysql.yml new file mode 100644 index 00000000..c05ce5e8 --- /dev/null +++ b/roles/icinga_kubernetes/tasks/manage_schema_mysql.yml @@ -0,0 +1,31 @@ +- name: MySQL import Kubernetes schema + when: icinga_kubernetes_database_import_schema | default(False) + block: + - name: Build mysql command + ansible.builtin.set_fact: + mysqlcmd: >- + mysql {% if icinga_kubernetes_database_host | default('localhost') != 'localhost' %} -h "{{ icinga_kubernetes_database_host }}" {%- endif %} + {% if icinga_kubernetes_database_port is defined %} -P {{ icinga_kubernetes_database_port }} {%- endif %} + {% if icinga_kubernetes_database_ca is defined %} --ssl-ca "{{ icinga_kubernetes_database_ca }}" {%- endif %} + {% if icinga_kubernetes_database_cert is defined %} --ssl-cert "{{ icinga_kubernetes_database_cert }}" {%- endif %} + {% if icinga_kubernetes_database_key is defined %} --ssl-key "{{ icinga_kubernetes_database_key }}" {%- endif %} + -u "{{ icinga_kubernetes_database_user | default('kubernetes') }}" + -p"{{ icinga_kubernetes_database_password }}" + "{{ icinga_kubernetes_database_name | default('kubernetes') }}" + + - name: MySQL check for Kubernetes schema + ansible.builtin.shell: > + {{ mysqlcmd }} + -Ns -e "select version from kubernetes_schema" + failed_when: false + changed_when: false + check_mode: false + register: _db_schema + + - name: MySQL import Kubernetes schema + ansible.builtin.shell: > + {{ mysqlcmd }} + < {{ icinga_kubernetes_database_schema }} + when: _db_schema.rc != 0 + check_mode: false + run_once: true diff --git a/roles/icinga_kubernetes/tasks/manage_schema_pgsql.yml b/roles/icinga_kubernetes/tasks/manage_schema_pgsql.yml new file mode 100644 index 00000000..07079629 --- /dev/null +++ b/roles/icinga_kubernetes/tasks/manage_schema_pgsql.yml @@ -0,0 +1,36 @@ +# temporarily disabled, pgsql at the moment is not available for icinga kubernetes + +# - name: PgSQL import Kubernetes schema +# when: icinga_kubernetes_database_import_schema| default(False) +# block: +# - name: Build pgsql command +# ansible.builtin.set_fact: +# _tmp_pgsqlcmd: >- +# PGPASSWORD="{{ icinga_kubernetes_database_password }}" +# psql +# "{% if icinga_kubernetes_database_host %} host="{{ icinga_kubernetes_database_host }}" {%- endif %} +# {% if icinga_kubernetes_database_port is defined %} port={{ icinga_kubernetes_database_port }} {%- endif %} +# user={{ icinga_kubernetes_database_user | default('kubernetes') }} +# dbname={{ icinga_kubernetes_database_name | default('kubernetes') }} +# {% if icinga_kubernetes_database_sslmode is defined %} sslmode={{ icinga_kubernetes_database_sslmode }} {%- endif %} +# {% if icinga_kubernetes_database_ca is defined %} sslrootcert={{ icinga_kubernetes_database_ca }} {%- endif %} +# {% if icinga_kubernetes_database_cert is defined %} sslcert={{ icinga_kubernetes_database_cert }} {%- endif %} +# {% if icinga_kubernetes_database_key is defined %} sslkey={{ icinga_kubernetes_database_key }} {%- endif %} +# {% if icinga_kubernetes_database_ssl_extra_options is defined %} {{ icinga_kubernetes_database_ssl_extra_options }} {%- endif %}" + +# - name: PgSQL check for Kubernetes schema +# ansible.builtin.shell: > +# {{ _tmp_pgsqlcmd }} +# -w -c "select version from kubernetes_schema" +# failed_when: false +# changed_when: false +# check_mode: false +# register: _db_schema + +# - name: PgSQL import Kubernetes schema +# ansible.builtin.shell: > +# {{ _tmp_pgsqlcmd }} +# -w -f {{ icinga_kubernetes_database_schema }} +# when: _db_schema.rc != 0 +# check_mode: false +# run_once: true diff --git a/roles/icinga_kubernetes/tasks/manage_service.yml b/roles/icinga_kubernetes/tasks/manage_service.yml new file mode 100644 index 00000000..93681f93 --- /dev/null +++ b/roles/icinga_kubernetes/tasks/manage_service.yml @@ -0,0 +1,27 @@ +--- +- name: Override KUBECONFIG path if defined + when: icinga_kubernetes_kubeconfig_path is defined + block: + - name: Create service override directory + ansible.builtin.file: + path: /etc/systemd/system/{{ icinga_kubernetes_service_name }}.service.d + state: directory + mode: '0755' + notify: + - Systemd reload + - Kubernetes-restart + + - name: Create service override configuration file + ansible.builtin.template: + src: icinga-kubernetes-override.conf.j2 + dest: "/etc/systemd/system/{{ icinga_kubernetes_service_name }}.service.d/override.conf" + mode: '0640' + notify: + - Systemd reload + - Kubernetes-restart + +- name: Ensure Kubernetes Service is running + ansible.builtin.service: + state: started + enabled: yes + name: "{{ icinga_kubernetes_service_name }}" diff --git a/roles/icinga_kubernetes/templates/icinga-kubernetes-override.conf.j2 b/roles/icinga_kubernetes/templates/icinga-kubernetes-override.conf.j2 new file mode 100644 index 00000000..504ecec7 --- /dev/null +++ b/roles/icinga_kubernetes/templates/icinga-kubernetes-override.conf.j2 @@ -0,0 +1,20 @@ +### Editing /etc/systemd/system/icinga-kubernetes.service.d/override.conf +### Anything between here and the comment below will become the new contents of the file + +[Service] +Environment="KUBECONFIG={{ icinga_kubernetes_kubeconfig_path }}" + +### Lines below this comment will be discarded + +### /lib/systemd/system/icinga-kubernetes.service +# [Unit] +# Description=Icinga for Kubernetes +# After=syslog.target network-online.target mariadb.service postgresql.service +# +# [Service] +# Type=simple +# ExecStart=/usr/sbin/icinga-kubernetes --config /etc/icinga-kubernetes/config.yml +# User=icinga-kubernetes +# +# [Install] +# WantedBy=multi-user.target \ No newline at end of file diff --git a/roles/icinga_kubernetes/templates/kubernetes.yml.j2 b/roles/icinga_kubernetes/templates/kubernetes.yml.j2 new file mode 100644 index 00000000..3080acb1 --- /dev/null +++ b/roles/icinga_kubernetes/templates/kubernetes.yml.j2 @@ -0,0 +1,18 @@ +# {{ ansible_managed | comment }} + +database: +{% if icinga_kubernetes_database_type is defined %} + type: {{ icinga_kubernetes_database_type }} +{% endif %} + host: {{ icinga_kubernetes_database_host | default('localhost') }} +{% if icinga_kubernetes_database_port is defined %} + port: {{ icinga_kubernetes_database_port }} +{% endif %} + database: {{ icinga_kubernetes_database_name | default('kubernetes') }} + user: {{ icinga_kubernetes_database_user | default('kubernetes') }} + password: {{ icinga_kubernetes_database_password | default('kubernetes') }} + +prometheus: +{% if icinga_kubernetes_prometheus_url is defined %} + url: {{ icinga_kubernetes_prometheus_url }} +{% endif %} diff --git a/roles/icinga_kubernetes/vars/default.yml b/roles/icinga_kubernetes/vars/default.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/roles/icinga_kubernetes/vars/default.yml @@ -0,0 +1 @@ +--- diff --git a/roles/icingaweb2/tasks/modules/kubernetes.yml b/roles/icingaweb2/tasks/modules/kubernetes.yml new file mode 100644 index 00000000..1537d179 --- /dev/null +++ b/roles/icingaweb2/tasks/modules/kubernetes.yml @@ -0,0 +1,18 @@ +- name: Module Icinga Kubernetes | Ensure config directory + ansible.builtin.file: + state: directory + dest: "{{ icingaweb2_modules_config_dir }}/{{ item.key }}" + owner: "{{ icingaweb2_httpd_user }}" + group: "{{ icingaweb2_group }}" + mode: "2770" + +- name: Module Icinga Kubernetes | 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 diff --git a/roles/icingaweb2/vars/main.yml b/roles/icingaweb2/vars/main.yml index 588f0d6d..18e3ec10 100644 --- a/roles/icingaweb2/vars/main.yml +++ b/roles/icingaweb2/vars/main.yml @@ -4,3 +4,4 @@ icingaweb2_module_packages: director: icinga-director x509: icinga-x509 businessprocess: icinga-businessprocess + kubernetes: icinga-kubernetes-web